Files
libreoffice/comphelper/source/container/enumerablemap.cxx
Thomas Arnhold ba0a57702c remove OUString wrap for string literals
For some functions and all kinds of Exceptions.

CannotConvertException
CloseVetoException
DisposedException
EmptyUndoStackException
ErrorCodeIOException
Exception
GridInvalidDataException
GridInvalidModelException
IOException
IllegalAccessException
IllegalArgumentException
IllegalTypeException
IndexOutOfBoundsException
NoMasterException
NoSuchElementException
NoSupportException
PropertyVetoException
RuntimeException
SAXException
ScannerException
StorageWrappedTargetException
UnsupportedFlavorException
VetoException
WrappedTargetException
ZipIOException
throwGenericSQLException
throwIllegallArgumentException

createInstance
createInstanceWithContext
forName
getByName
getPackageManager
getPropertyValue
getUnpackedValueOrDefault
getValueByName
hasPropertyByName
openKey
setName
setPropertyValue
supportsService

bash command:

for i in `cat list`; do git grep "$i\s*(\s*OUString(\s*\"" -- '*.[hc]xx'
	| cut -d ':' -f1 | sort -u
	| xargs sed -i
		-e "s/\(\<$i\s*(\)\s*OUString(\s*\(\"[^\")\\]*\"\)\s*)\s*/\1\2/g"
		-e "s/\($i.*\)\"+ /\1\" + /g";
done

Change-Id: Iaf8e641b0abf28c082906014f87a183517630535
Reviewed-on: https://gerrit.libreoffice.org/4624
Tested-by: LibreOffice gerrit bot <gerrit@libreoffice.org>
Reviewed-by: Thomas Arnhold <thomas@arnhold.org>
Tested-by: Thomas Arnhold <thomas@arnhold.org>
2013-06-29 21:52:54 +00:00

795 lines
32 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "comphelper_module.hxx"
#include "comphelper/anytostring.hxx"
#include "comphelper/anycompare.hxx"
#include "comphelper/componentbase.hxx"
#include "comphelper/extract.hxx"
#include <com/sun/star/container/XEnumerableMap.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
#include <com/sun/star/beans/Pair.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <cppuhelper/compbase3.hxx>
#include <cppuhelper/implbase1.hxx>
#include <rtl/math.hxx>
#include <rtl/ustrbuf.hxx>
#include <typelib/typedescription.hxx>
#include <map>
#include <boost/shared_ptr.hpp>
//........................................................................
namespace comphelper
{
//........................................................................
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::UNO_QUERY_THROW;
using ::com::sun::star::uno::UNO_SET_THROW;
using ::com::sun::star::uno::Exception;
using ::com::sun::star::uno::RuntimeException;
using ::com::sun::star::uno::Any;
using ::com::sun::star::uno::makeAny;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Type;
using ::com::sun::star::container::XEnumerableMap;
using ::com::sun::star::lang::NoSupportException;
using ::com::sun::star::beans::IllegalTypeException;
using ::com::sun::star::container::NoSuchElementException;
using ::com::sun::star::lang::IllegalArgumentException;
using ::com::sun::star::lang::XInitialization;
using ::com::sun::star::ucb::AlreadyInitializedException;
using ::com::sun::star::beans::Pair;
using ::com::sun::star::uno::TypeClass;
using ::com::sun::star::uno::TypeClass_VOID;
using ::com::sun::star::uno::TypeClass_UNKNOWN;
using ::com::sun::star::uno::TypeClass_ANY;
using ::com::sun::star::uno::TypeClass_EXCEPTION;
using ::com::sun::star::uno::TypeClass_STRUCT;
using ::com::sun::star::uno::TypeClass_UNION;
using ::com::sun::star::uno::TypeClass_FLOAT;
using ::com::sun::star::uno::TypeClass_DOUBLE;
using ::com::sun::star::uno::TypeClass_INTERFACE;
using ::com::sun::star::lang::XServiceInfo;
using ::com::sun::star::uno::XComponentContext;
using ::com::sun::star::container::XEnumeration;
using ::com::sun::star::uno::TypeDescription;
using ::com::sun::star::lang::WrappedTargetException;
using ::com::sun::star::lang::DisposedException;
//====================================================================
//= MapData
//====================================================================
class IMapModificationListener;
typedef ::std::vector< IMapModificationListener* > MapListeners;
typedef ::std::map< Any, Any, LessPredicateAdapter > KeyedValues;
struct MapData
{
Type m_aKeyType;
Type m_aValueType;
::std::auto_ptr< KeyedValues > m_pValues;
::boost::shared_ptr< IKeyPredicateLess > m_pKeyCompare;
bool m_bMutable;
MapListeners m_aModListeners;
MapData()
:m_bMutable( true )
{
}
MapData( const MapData& _source )
:m_aKeyType( _source.m_aKeyType )
,m_aValueType( _source.m_aValueType )
,m_pValues( new KeyedValues( *_source.m_pValues ) )
,m_pKeyCompare( _source.m_pKeyCompare )
,m_bMutable( false )
,m_aModListeners()
{
}
private:
MapData& operator=( const MapData& _source ); // not implemented
};
//====================================================================
//= IMapModificationListener
//====================================================================
/** implemented by components who want to be notified of modifications in the MapData they work with
*/
class SAL_NO_VTABLE IMapModificationListener
{
public:
/// called when the map was modified
virtual void mapModified() = 0;
virtual ~IMapModificationListener()
{
}
};
//====================================================================
//= MapData helpers
//====================================================================
//--------------------------------------------------------------------
static void lcl_registerMapModificationListener( MapData& _mapData, IMapModificationListener& _listener )
{
#if OSL_DEBUG_LEVEL > 0
for ( MapListeners::const_iterator lookup = _mapData.m_aModListeners.begin();
lookup != _mapData.m_aModListeners.end();
++lookup
)
{
OSL_ENSURE( *lookup != &_listener, "lcl_registerMapModificationListener: this listener is already registered!" );
}
#endif
_mapData.m_aModListeners.push_back( &_listener );
}
//--------------------------------------------------------------------
static void lcl_revokeMapModificationListener( MapData& _mapData, IMapModificationListener& _listener )
{
for ( MapListeners::iterator lookup = _mapData.m_aModListeners.begin();
lookup != _mapData.m_aModListeners.end();
++lookup
)
{
if ( *lookup == &_listener )
{
_mapData.m_aModListeners.erase( lookup );
return;
}
}
OSL_FAIL( "lcl_revokeMapModificationListener: the listener is not registered!" );
}
//--------------------------------------------------------------------
static void lcl_notifyMapDataListeners_nothrow( const MapData& _mapData )
{
for ( MapListeners::const_iterator loop = _mapData.m_aModListeners.begin();
loop != _mapData.m_aModListeners.end();
++loop
)
{
(*loop)->mapModified();
}
}
//====================================================================
//= EnumerableMap
//====================================================================
typedef ::cppu::WeakAggComponentImplHelper3 < XInitialization
, XEnumerableMap
, XServiceInfo
> Map_IFace;
class COMPHELPER_DLLPRIVATE EnumerableMap :public Map_IFace
,public ComponentBase
{
protected:
EnumerableMap();
virtual ~EnumerableMap();
// XInitialization
virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
// XEnumerableMap
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);
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);
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);
// XMap
virtual Type SAL_CALL getKeyType() throw (RuntimeException);
virtual Type SAL_CALL getValueType() throw (RuntimeException);
virtual void SAL_CALL clear( ) throw (NoSupportException, RuntimeException);
virtual ::sal_Bool SAL_CALL containsKey( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException);
virtual ::sal_Bool SAL_CALL containsValue( const Any& _value ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException);
virtual Any SAL_CALL get( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException);
virtual Any SAL_CALL put( const Any& _key, const Any& _value ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, RuntimeException);
virtual Any SAL_CALL remove( const Any& _key ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException);
// XElementAccess (base of XMap)
virtual Type SAL_CALL getElementType() throw (RuntimeException);
virtual ::sal_Bool SAL_CALL hasElements() throw (RuntimeException);
// XServiceInfo
virtual OUString SAL_CALL getImplementationName( ) throw (RuntimeException);
virtual ::sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw (RuntimeException);
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException);
public:
// XServiceInfo, static version (used for component registration)
static OUString SAL_CALL getImplementationName_static( );
static Sequence< OUString > SAL_CALL getSupportedServiceNames_static( );
static Reference< XInterface > SAL_CALL Create( const Reference< XComponentContext >& );
private:
void impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues );
/// throws a IllegalTypeException if the given value is not compatible with our ValueType
void impl_checkValue_throw( const Any& _value ) const;
void impl_checkKey_throw( const Any& _key ) const;
void impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const;
void impl_checkMutable_throw() const;
private:
::osl::Mutex m_aMutex;
MapData m_aData;
::std::vector< ::com::sun::star::uno::WeakReference< XInterface > >
m_aDependentComponents;
};
//====================================================================
//= EnumerationType
//====================================================================
enum EnumerationType
{
eKeys, eValues, eBoth
};
//====================================================================
//= MapEnumerator
//====================================================================
class MapEnumerator : public IMapModificationListener
{
public:
MapEnumerator( ::cppu::OWeakObject& _rParent, MapData& _mapData, const EnumerationType _type )
:m_rParent( _rParent )
,m_rMapData( _mapData )
,m_eType( _type )
,m_mapPos( _mapData.m_pValues->begin() )
,m_disposed( false )
{
lcl_registerMapModificationListener( m_rMapData, *this );
}
virtual ~MapEnumerator()
{
dispose();
}
void dispose()
{
if ( !m_disposed )
{
lcl_revokeMapModificationListener( m_rMapData, *this );
m_disposed = true;
}
}
// XEnumeration equivalents
::sal_Bool hasMoreElements();
Any nextElement();
// IMapModificationListener
virtual void mapModified();
private:
::cppu::OWeakObject& m_rParent;
MapData& m_rMapData;
const EnumerationType m_eType;
KeyedValues::const_iterator m_mapPos;
bool m_disposed;
private:
MapEnumerator(); // not implemented
MapEnumerator( const MapEnumerator& ); // not implemented
MapEnumerator& operator=( const MapEnumerator& ); // not implemented
};
//====================================================================
//= MapEnumeration
//====================================================================
typedef ::cppu::WeakImplHelper1 < XEnumeration
> MapEnumeration_Base;
class MapEnumeration :public ComponentBase
,public MapEnumeration_Base
{
public:
MapEnumeration( ::cppu::OWeakObject& _parentMap, MapData& _mapData, ::cppu::OBroadcastHelper& _rBHelper,
const EnumerationType _type, const bool _isolated )
:ComponentBase( _rBHelper, ComponentBase::NoInitializationNeeded() )
,m_xKeepMapAlive( _parentMap )
,m_pMapDataCopy( _isolated ? new MapData( _mapData ) : NULL )
,m_aEnumerator( *this, _isolated ? *m_pMapDataCopy : _mapData, _type )
{
}
// XEnumeration
virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (RuntimeException);
virtual Any SAL_CALL nextElement( ) throw (NoSuchElementException, WrappedTargetException, RuntimeException);
protected:
virtual ~MapEnumeration()
{
acquire();
{
::osl::MutexGuard aGuard( getMutex() );
m_aEnumerator.dispose();
m_pMapDataCopy.reset();
}
}
private:
// sicne we share our mutex with the main map, we need to keep it alive as long as we live
Reference< XInterface > m_xKeepMapAlive;
::std::auto_ptr< MapData > m_pMapDataCopy;
MapEnumerator m_aEnumerator;
};
//====================================================================
//= EnumerableMap
//====================================================================
//--------------------------------------------------------------------
EnumerableMap::EnumerableMap()
:Map_IFace( m_aMutex )
,ComponentBase( Map_IFace::rBHelper )
{
}
//--------------------------------------------------------------------
EnumerableMap::~EnumerableMap()
{
if ( !impl_isDisposed() )
{
acquire();
dispose();
}
}
//--------------------------------------------------------------------
void SAL_CALL EnumerableMap::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException)
{
ComponentMethodGuard aGuard( *this, ComponentMethodGuard::WithoutInit );
if ( impl_isInitialized_nothrow() )
throw AlreadyInitializedException();
sal_Int32 nArgumentCount = _arguments.getLength();
if ( ( nArgumentCount != 2 ) && ( nArgumentCount != 3 ) )
throw IllegalArgumentException();
Type aKeyType, aValueType;
if ( !( _arguments[0] >>= aKeyType ) )
throw IllegalArgumentException("com.sun.star.uno.Type expected.", *this, 1 );
if ( !( _arguments[1] >>= aValueType ) )
throw IllegalArgumentException("com.sun.star.uno.Type expected.", *this, 2 );
Sequence< Pair< Any, Any > > aInitialValues;
bool bMutable = true;
if ( nArgumentCount == 3 )
{
if ( !( _arguments[2] >>= aInitialValues ) )
throw IllegalArgumentException("[]com.sun.star.beans.Pair<any,any> expected.", *this, 2 );
bMutable = false;
}
// for the value, anything is allowed, except VOID
if ( ( aValueType.getTypeClass() == TypeClass_VOID ) || ( aValueType.getTypeClass() == TypeClass_UNKNOWN ) )
throw IllegalTypeException("Unsupported value type.", *this );
// create the comparator for the KeyType, and throw if the type is not supported
::std::auto_ptr< IKeyPredicateLess > pComparator( getStandardLessPredicate( aKeyType, NULL ) );
if ( !pComparator.get() )
throw IllegalTypeException("Unsupported key type.", *this );
// init members
m_aData.m_aKeyType = aKeyType;
m_aData.m_aValueType = aValueType;
m_aData.m_pKeyCompare = pComparator;
m_aData.m_pValues.reset( new KeyedValues( *m_aData.m_pKeyCompare ) );
m_aData.m_bMutable = bMutable;
if ( aInitialValues.getLength() )
impl_initValues_throw( aInitialValues );
setInitialized();
}
//--------------------------------------------------------------------
void EnumerableMap::impl_initValues_throw( const Sequence< Pair< Any, Any > >& _initialValues )
{
OSL_PRECOND( m_aData.m_pValues.get() && m_aData.m_pValues->empty(), "EnumerableMap::impl_initValues_throw: illegal call!" );
if ( !m_aData.m_pValues.get() || !m_aData.m_pValues->empty() )
throw RuntimeException();
const Pair< Any, Any >* mapping = _initialValues.getConstArray();
const Pair< Any, Any >* mappingEnd = mapping + _initialValues.getLength();
Any normalizedValue;
for ( ; mapping != mappingEnd; ++mapping )
{
impl_checkValue_throw( mapping->Second );
(*m_aData.m_pValues)[ mapping->First ] = mapping->Second;
}
}
//--------------------------------------------------------------------
void EnumerableMap::impl_checkValue_throw( const Any& _value ) const
{
if ( !_value.hasValue() )
// nothing to do, NULL values are always allowed, regardless of the ValueType
return;
TypeClass eAllowedTypeClass = m_aData.m_aValueType.getTypeClass();
bool bValid = false;
switch ( eAllowedTypeClass )
{
default:
bValid = ( _value.getValueTypeClass() == eAllowedTypeClass );
break;
case TypeClass_ANY:
bValid = true;
break;
case TypeClass_INTERFACE:
{
// special treatment: _value might contain the proper type, but the interface
// might actually be NULL. Which is still valid ...
if ( m_aData.m_aValueType.isAssignableFrom( _value.getValueType() ) )
// this also catches the special case where XFoo is our value type,
// and _value contains a NULL-reference to XFoo, or a derived type
bValid = true;
else
{
Reference< XInterface > xValue( _value, UNO_QUERY );
Any aTypedValue;
if ( xValue.is() )
// XInterface is not-NULL, but is X(ValueType) not-NULL, too?
xValue.set( xValue->queryInterface( m_aData.m_aValueType ), UNO_QUERY );
bValid = xValue.is();
}
}
break;
case TypeClass_EXCEPTION:
case TypeClass_STRUCT:
case TypeClass_UNION:
{
// values are accepted if and only if their type equals, or is derived from, our value type
if ( _value.getValueTypeClass() != eAllowedTypeClass )
bValid = false;
else
{
const TypeDescription aValueTypeDesc( _value.getValueType() );
const TypeDescription aRequiredTypeDesc( m_aData.m_aValueType );
const _typelib_CompoundTypeDescription* pValueCompoundTypeDesc =
reinterpret_cast< const _typelib_CompoundTypeDescription* >( aValueTypeDesc.get() );
while ( pValueCompoundTypeDesc )
{
if ( typelib_typedescription_equals( &pValueCompoundTypeDesc->aBase, aRequiredTypeDesc.get() ) )
break;
pValueCompoundTypeDesc = pValueCompoundTypeDesc->pBaseTypeDescription;
}
bValid = ( pValueCompoundTypeDesc != NULL );
}
}
break;
}
if ( !bValid )
{
OUStringBuffer aMessage;
aMessage.appendAscii( "Incompatible value type. Found '" );
aMessage.append( _value.getValueTypeName() );
aMessage.appendAscii( "', where '" );
aMessage.append( m_aData.m_aValueType.getTypeName() );
aMessage.appendAscii( "' (or compatible type) is expected." );
throw IllegalTypeException( aMessage.makeStringAndClear(), *const_cast< EnumerableMap* >( this ) );
}
impl_checkNaN_throw( _value, m_aData.m_aValueType );
}
//--------------------------------------------------------------------
void EnumerableMap::impl_checkNaN_throw( const Any& _keyOrValue, const Type& _keyOrValueType ) const
{
if ( ( _keyOrValueType.getTypeClass() == TypeClass_DOUBLE )
|| ( _keyOrValueType.getTypeClass() == TypeClass_FLOAT )
)
{
double nValue(0);
if ( _keyOrValue >>= nValue )
if ( ::rtl::math::isNan( nValue ) )
throw IllegalArgumentException(
OUString( "NaN (not-a-number) not supported by this implementation." ),
*const_cast< EnumerableMap* >( this ), 0 );
// (note that the case of _key not containing a float/double value is handled in the
// respective IKeyPredicateLess implementation, so there's no need to handle this here.)
}
}
//--------------------------------------------------------------------
void EnumerableMap::impl_checkKey_throw( const Any& _key ) const
{
if ( !_key.hasValue() )
throw IllegalArgumentException(
OUString( "NULL keys not supported by this implementation." ),
*const_cast< EnumerableMap* >( this ), 0 );
impl_checkNaN_throw( _key, m_aData.m_aKeyType );
}
//--------------------------------------------------------------------
void EnumerableMap::impl_checkMutable_throw() const
{
if ( !m_aData.m_bMutable )
throw NoSupportException(
OUString( "The map is immutable." ),
*const_cast< EnumerableMap* >( this ) );
}
//--------------------------------------------------------------------
Reference< XEnumeration > SAL_CALL EnumerableMap::createKeyEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eKeys, _Isolated );
}
//--------------------------------------------------------------------
Reference< XEnumeration > SAL_CALL EnumerableMap::createValueEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eValues, _Isolated );
}
//--------------------------------------------------------------------
Reference< XEnumeration > SAL_CALL EnumerableMap::createElementEnumeration( ::sal_Bool _Isolated ) throw (NoSupportException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return new MapEnumeration( *this, m_aData, getBroadcastHelper(), eBoth, _Isolated );
}
//--------------------------------------------------------------------
Type SAL_CALL EnumerableMap::getKeyType() throw (RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return m_aData.m_aKeyType;
}
//--------------------------------------------------------------------
Type SAL_CALL EnumerableMap::getValueType() throw (RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return m_aData.m_aValueType;
}
//--------------------------------------------------------------------
void SAL_CALL EnumerableMap::clear( ) throw (NoSupportException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
impl_checkMutable_throw();
m_aData.m_pValues->clear();
lcl_notifyMapDataListeners_nothrow( m_aData );
}
//--------------------------------------------------------------------
::sal_Bool SAL_CALL EnumerableMap::containsKey( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
impl_checkKey_throw( _key );
KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key );
return ( pos != m_aData.m_pValues->end() );
}
//--------------------------------------------------------------------
::sal_Bool SAL_CALL EnumerableMap::containsValue( const Any& _value ) throw (IllegalTypeException, IllegalArgumentException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
impl_checkValue_throw( _value );
for ( KeyedValues::const_iterator mapping = m_aData.m_pValues->begin();
mapping != m_aData.m_pValues->end();
++mapping
)
{
if ( mapping->second == _value )
return sal_True;
}
return sal_False;
}
//--------------------------------------------------------------------
Any SAL_CALL EnumerableMap::get( const Any& _key ) throw (IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
impl_checkKey_throw( _key );
KeyedValues::const_iterator pos = m_aData.m_pValues->find( _key );
if ( pos == m_aData.m_pValues->end() )
throw NoSuchElementException( anyToString( _key ), *this );
return pos->second;
}
//--------------------------------------------------------------------
Any SAL_CALL EnumerableMap::put( const Any& _key, const Any& _value ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
impl_checkMutable_throw();
impl_checkKey_throw( _key );
impl_checkValue_throw( _value );
Any previousValue;
KeyedValues::iterator pos = m_aData.m_pValues->find( _key );
if ( pos != m_aData.m_pValues->end() )
{
previousValue = pos->second;
pos->second = _value;
}
else
{
(*m_aData.m_pValues)[ _key ] = _value;
}
lcl_notifyMapDataListeners_nothrow( m_aData );
return previousValue;
}
//--------------------------------------------------------------------
Any SAL_CALL EnumerableMap::remove( const Any& _key ) throw (NoSupportException, IllegalTypeException, IllegalArgumentException, NoSuchElementException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
impl_checkMutable_throw();
impl_checkKey_throw( _key );
Any previousValue;
KeyedValues::iterator pos = m_aData.m_pValues->find( _key );
if ( pos != m_aData.m_pValues->end() )
{
previousValue = pos->second;
m_aData.m_pValues->erase( pos );
}
lcl_notifyMapDataListeners_nothrow( m_aData );
return previousValue;
}
//--------------------------------------------------------------------
Type SAL_CALL EnumerableMap::getElementType() throw (RuntimeException)
{
return ::cppu::UnoType< Pair< Any, Any > >::get();
}
//--------------------------------------------------------------------
::sal_Bool SAL_CALL EnumerableMap::hasElements() throw (RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return m_aData.m_pValues->empty();
}
//--------------------------------------------------------------------
OUString SAL_CALL EnumerableMap::getImplementationName( ) throw (RuntimeException)
{
return getImplementationName_static();
}
//--------------------------------------------------------------------
::sal_Bool SAL_CALL EnumerableMap::supportsService( const OUString& _serviceName ) throw (RuntimeException)
{
Sequence< OUString > aServices( getSupportedServiceNames() );
for ( sal_Int32 i=0; i<aServices.getLength(); ++i )
if ( _serviceName == aServices[i] )
return sal_True;
return sal_False;
}
//--------------------------------------------------------------------
Sequence< OUString > SAL_CALL EnumerableMap::getSupportedServiceNames( ) throw (RuntimeException)
{
return getSupportedServiceNames_static();
}
//--------------------------------------------------------------------
OUString SAL_CALL EnumerableMap::getImplementationName_static( )
{
return OUString( "org.openoffice.comp.comphelper.EnumerableMap" );
}
//--------------------------------------------------------------------
Sequence< OUString > SAL_CALL EnumerableMap::getSupportedServiceNames_static( )
{
Sequence< OUString > aServiceNames(1);
aServiceNames[0] = "com.sun.star.container.EnumerableMap";
return aServiceNames;
}
//--------------------------------------------------------------------
Reference< XInterface > SAL_CALL EnumerableMap::Create( SAL_UNUSED_PARAMETER const Reference< XComponentContext >& )
{
return *new EnumerableMap;
}
//====================================================================
//= MapEnumerator
//====================================================================
//--------------------------------------------------------------------
::sal_Bool MapEnumerator::hasMoreElements()
{
if ( m_disposed )
throw DisposedException( OUString(), m_rParent );
return m_mapPos != m_rMapData.m_pValues->end();
}
//--------------------------------------------------------------------
Any MapEnumerator::nextElement()
{
if ( m_disposed )
throw DisposedException( OUString(), m_rParent );
if ( m_mapPos == m_rMapData.m_pValues->end() )
throw NoSuchElementException("No more elements.", m_rParent );
Any aNextElement;
switch ( m_eType )
{
case eKeys: aNextElement = m_mapPos->first; break;
case eValues: aNextElement = m_mapPos->second; break;
case eBoth: aNextElement <<= Pair< Any, Any >( m_mapPos->first, m_mapPos->second ); break;
}
++m_mapPos;
return aNextElement;
}
//--------------------------------------------------------------------
void MapEnumerator::mapModified()
{
m_disposed = true;
}
//====================================================================
//= MapEnumeration - implementation
//====================================================================
//--------------------------------------------------------------------
::sal_Bool SAL_CALL MapEnumeration::hasMoreElements( ) throw (RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return m_aEnumerator.hasMoreElements();
}
//--------------------------------------------------------------------
Any SAL_CALL MapEnumeration::nextElement( ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
{
ComponentMethodGuard aGuard( *this );
return m_aEnumerator.nextElement();
}
//........................................................................
} // namespace comphelper
//........................................................................
void createRegistryInfo_Map()
{
::comphelper::module::OAutoRegistration< ::comphelper::EnumerableMap > aAutoRegistration;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */