1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: namedvaluecollection.cxx,v $
10 * $Revision: 1.11.30.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
33 #include <comphelper/namedvaluecollection.hxx>
35 /** === begin UNO includes === **/
36 #include <com/sun/star/beans/NamedValue.hpp>
37 #include <com/sun/star/lang/IllegalArgumentException.hpp>
38 #include <com/sun/star/beans/PropertyState.hpp>
39 /** === end UNO includes === **/
41 #include <rtl/ustrbuf.hxx>
42 #include <rtl/strbuf.hxx>
43 #include <osl/diagnose.h>
49 //........................................................................
52 //........................................................................
54 /** === begin UNO using === **/
55 using ::com::sun::star::uno::Any
;
56 using ::com::sun::star::uno::Sequence
;
57 using ::com::sun::star::beans::PropertyValue
;
58 using ::com::sun::star::beans::NamedValue
;
59 using ::com::sun::star::uno::Type
;
60 using ::com::sun::star::uno::cpp_acquire
;
61 using ::com::sun::star::uno::cpp_release
;
62 using ::com::sun::star::uno::cpp_queryInterface
;
63 using ::com::sun::star::lang::IllegalArgumentException
;
64 using ::com::sun::star::beans::NamedValue
;
65 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
66 /** === end UNO using === **/
68 //====================================================================
69 //= NamedValueCollection_Impl
70 //====================================================================
71 typedef ::std::hash_map
< ::rtl::OUString
, Any
, ::rtl::OUStringHash
> NamedValueRepository
;
73 struct NamedValueCollection_Impl
75 NamedValueRepository aValues
;
78 //====================================================================
79 //= NamedValueCollection
80 //====================================================================
81 //--------------------------------------------------------------------
82 NamedValueCollection::NamedValueCollection()
83 :m_pImpl( new NamedValueCollection_Impl
)
87 //--------------------------------------------------------------------
88 NamedValueCollection::NamedValueCollection( const NamedValueCollection
& _rCopySource
)
89 :m_pImpl( new NamedValueCollection_Impl
)
91 m_pImpl
->aValues
= _rCopySource
.m_pImpl
->aValues
;
94 //--------------------------------------------------------------------
95 NamedValueCollection::NamedValueCollection( const Any
& _rElements
)
96 :m_pImpl( new NamedValueCollection_Impl
)
98 Sequence
< NamedValue
> aNamedValues
;
99 Sequence
< PropertyValue
> aPropertyValues
;
100 NamedValue aNamedValue
;
101 PropertyValue aPropertyValue
;
103 if ( _rElements
>>= aNamedValues
)
104 impl_assign( aNamedValues
);
105 else if ( _rElements
>>= aPropertyValues
)
106 impl_assign( aPropertyValues
);
107 else if ( _rElements
>>= aNamedValue
)
108 impl_assign( Sequence
< NamedValue
>( &aNamedValue
, 1 ) );
109 else if ( _rElements
>>= aPropertyValue
)
110 impl_assign( Sequence
< PropertyValue
>( &aPropertyValue
, 1 ) );
112 OSL_ENSURE( !_rElements
.hasValue(), "NamedValueCollection::NamedValueCollection(Any): unsupported type!" );
115 //--------------------------------------------------------------------
116 NamedValueCollection::NamedValueCollection( const Sequence
< Any
>& _rArguments
)
117 :m_pImpl( new NamedValueCollection_Impl
)
119 impl_assign( _rArguments
);
122 //--------------------------------------------------------------------
123 NamedValueCollection::NamedValueCollection( const Sequence
< PropertyValue
>& _rArguments
)
124 :m_pImpl( new NamedValueCollection_Impl
)
126 impl_assign( _rArguments
);
129 //--------------------------------------------------------------------
130 NamedValueCollection::NamedValueCollection( const Sequence
< NamedValue
>& _rArguments
)
131 :m_pImpl( new NamedValueCollection_Impl
)
133 impl_assign( _rArguments
);
136 //--------------------------------------------------------------------
137 NamedValueCollection::~NamedValueCollection()
141 //--------------------------------------------------------------------
142 NamedValueCollection
& NamedValueCollection::merge( const NamedValueCollection
& _rAdditionalValues
, bool _bOverwriteExisting
)
144 for ( NamedValueRepository::const_iterator namedValue
= _rAdditionalValues
.m_pImpl
->aValues
.begin();
145 namedValue
!= _rAdditionalValues
.m_pImpl
->aValues
.end();
149 if ( _bOverwriteExisting
|| !impl_has( namedValue
->first
) )
150 impl_put( namedValue
->first
, namedValue
->second
);
156 //--------------------------------------------------------------------
157 size_t NamedValueCollection::size() const
159 return m_pImpl
->aValues
.size();
162 //--------------------------------------------------------------------
163 bool NamedValueCollection::empty() const
165 return m_pImpl
->aValues
.empty();
168 //--------------------------------------------------------------------
169 void NamedValueCollection::impl_assign( const Sequence
< Any
>& _rArguments
)
172 NamedValueRepository aEmpty
;
173 m_pImpl
->aValues
.swap( aEmpty
);
176 PropertyValue aPropertyValue
;
177 NamedValue aNamedValue
;
179 const Any
* pArgument
= _rArguments
.getConstArray();
180 const Any
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
181 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
183 if ( *pArgument
>>= aPropertyValue
)
184 m_pImpl
->aValues
[ aPropertyValue
.Name
] = aPropertyValue
.Value
;
185 else if ( *pArgument
>>= aNamedValue
)
186 m_pImpl
->aValues
[ aNamedValue
.Name
] = aNamedValue
.Value
;
187 #if OSL_DEBUG_LEVEL > 0
188 else if ( pArgument
->hasValue() )
190 ::rtl::OStringBuffer message
;
191 message
.append( "NamedValueCollection::impl_assign: encountered a value type which I cannot handle:\n" );
192 message
.append( ::rtl::OUStringToOString( pArgument
->getValueTypeName(), RTL_TEXTENCODING_ASCII_US
) );
193 OSL_ENSURE( false, message
.makeStringAndClear() );
199 //--------------------------------------------------------------------
200 void NamedValueCollection::impl_assign( const Sequence
< PropertyValue
>& _rArguments
)
203 NamedValueRepository aEmpty
;
204 m_pImpl
->aValues
.swap( aEmpty
);
207 const PropertyValue
* pArgument
= _rArguments
.getConstArray();
208 const PropertyValue
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
209 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
210 m_pImpl
->aValues
[ pArgument
->Name
] = pArgument
->Value
;
213 //--------------------------------------------------------------------
214 void NamedValueCollection::impl_assign( const Sequence
< NamedValue
>& _rArguments
)
217 NamedValueRepository aEmpty
;
218 m_pImpl
->aValues
.swap( aEmpty
);
221 const NamedValue
* pArgument
= _rArguments
.getConstArray();
222 const NamedValue
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
223 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
224 m_pImpl
->aValues
[ pArgument
->Name
] = pArgument
->Value
;
227 //--------------------------------------------------------------------
228 bool NamedValueCollection::get_ensureType( const ::rtl::OUString
& _rValueName
, void* _pValueLocation
, const Type
& _rExpectedValueType
) const
230 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
231 if ( pos
!= m_pImpl
->aValues
.end() )
233 if ( uno_type_assignData(
234 _pValueLocation
, _rExpectedValueType
.getTypeLibType(),
235 const_cast< void* >( pos
->second
.getValue() ), pos
->second
.getValueType().getTypeLibType(),
236 reinterpret_cast< uno_QueryInterfaceFunc
>( cpp_queryInterface
),
237 reinterpret_cast< uno_AcquireFunc
>( cpp_acquire
),
238 reinterpret_cast< uno_ReleaseFunc
>( cpp_release
)
240 // argument exists, and could be extracted
243 // argument exists, but is of wrong type
244 ::rtl::OUStringBuffer aBuffer
;
245 aBuffer
.appendAscii( "Invalid value type for '" );
246 aBuffer
.append ( _rValueName
);
247 aBuffer
.appendAscii( "'.\nExpected: " );
248 aBuffer
.append ( _rExpectedValueType
.getTypeName() );
249 aBuffer
.appendAscii( "\nFound: " );
250 aBuffer
.append ( pos
->second
.getValueType().getTypeName() );
251 throw IllegalArgumentException( aBuffer
.makeStringAndClear(), NULL
, 0 );
254 // argument does not exist
258 //--------------------------------------------------------------------
259 const Any
& NamedValueCollection::impl_get( const ::rtl::OUString
& _rValueName
) const
261 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
262 if ( pos
!= m_pImpl
->aValues
.end() )
265 static Any aEmptyDefault
;
266 return aEmptyDefault
;
269 //--------------------------------------------------------------------
270 bool NamedValueCollection::impl_has( const ::rtl::OUString
& _rValueName
) const
272 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
273 return ( pos
!= m_pImpl
->aValues
.end() );
276 //--------------------------------------------------------------------
277 bool NamedValueCollection::impl_put( const ::rtl::OUString
& _rValueName
, const Any
& _rValue
)
279 bool bHas
= impl_has( _rValueName
);
280 m_pImpl
->aValues
[ _rValueName
] = _rValue
;
284 //--------------------------------------------------------------------
285 bool NamedValueCollection::impl_remove( const ::rtl::OUString
& _rValueName
)
287 NamedValueRepository::iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
288 if ( pos
== m_pImpl
->aValues
.end() )
290 m_pImpl
->aValues
.erase( pos
);
294 //--------------------------------------------------------------------
297 struct Value2PropertyValue
: public ::std::unary_function
< NamedValueRepository::value_type
, PropertyValue
>
299 PropertyValue
operator()( const NamedValueRepository::value_type
& _rValue
)
301 return PropertyValue(
302 _rValue
.first
, 0, _rValue
.second
, PropertyState_DIRECT_VALUE
);
306 struct Value2NamedValue
: public ::std::unary_function
< NamedValueRepository::value_type
, NamedValue
>
308 NamedValue
operator()( const NamedValueRepository::value_type
& _rValue
)
310 return NamedValue( _rValue
.first
, _rValue
.second
);
315 //--------------------------------------------------------------------
316 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< PropertyValue
>& _out_rValues
) const
318 _out_rValues
.realloc( m_pImpl
->aValues
.size() );
319 ::std::transform( m_pImpl
->aValues
.begin(), m_pImpl
->aValues
.end(), _out_rValues
.getArray(), Value2PropertyValue() );
320 return _out_rValues
.getLength();
323 //--------------------------------------------------------------------
324 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< NamedValue
>& _out_rValues
) const
326 _out_rValues
.realloc( m_pImpl
->aValues
.size() );
327 ::std::transform( m_pImpl
->aValues
.begin(), m_pImpl
->aValues
.end(), _out_rValues
.getArray(), Value2NamedValue() );
328 return _out_rValues
.getLength();
331 //........................................................................
332 } // namespace comphelper
333 //........................................................................