1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
30 #include <comphelper/namedvaluecollection.hxx>
32 /** === begin UNO includes === **/
33 #include <com/sun/star/beans/NamedValue.hpp>
34 #include <com/sun/star/lang/IllegalArgumentException.hpp>
35 #include <com/sun/star/beans/PropertyState.hpp>
36 /** === end UNO includes === **/
38 #include <rtl/ustrbuf.hxx>
39 #include <rtl/strbuf.hxx>
40 #include <osl/diagnose.h>
46 //........................................................................
49 //........................................................................
51 /** === begin UNO using === **/
52 using ::com::sun::star::uno::Any
;
53 using ::com::sun::star::uno::Sequence
;
54 using ::com::sun::star::beans::PropertyValue
;
55 using ::com::sun::star::beans::NamedValue
;
56 using ::com::sun::star::uno::Type
;
57 using ::com::sun::star::uno::cpp_acquire
;
58 using ::com::sun::star::uno::cpp_release
;
59 using ::com::sun::star::uno::cpp_queryInterface
;
60 using ::com::sun::star::lang::IllegalArgumentException
;
61 using ::com::sun::star::beans::NamedValue
;
62 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
63 /** === end UNO using === **/
65 //====================================================================
66 //= NamedValueCollection_Impl
67 //====================================================================
68 typedef ::std::hash_map
< ::rtl::OUString
, Any
, ::rtl::OUStringHash
> NamedValueRepository
;
70 struct NamedValueCollection_Impl
72 NamedValueRepository aValues
;
75 //====================================================================
76 //= NamedValueCollection
77 //====================================================================
78 //--------------------------------------------------------------------
79 NamedValueCollection::NamedValueCollection()
80 :m_pImpl( new NamedValueCollection_Impl
)
84 //--------------------------------------------------------------------
85 NamedValueCollection::NamedValueCollection( const NamedValueCollection
& _rCopySource
)
86 :m_pImpl( new NamedValueCollection_Impl
)
91 //--------------------------------------------------------------------
92 NamedValueCollection
& NamedValueCollection::operator=( const NamedValueCollection
& i_rCopySource
)
94 m_pImpl
->aValues
= i_rCopySource
.m_pImpl
->aValues
;
98 //--------------------------------------------------------------------
99 NamedValueCollection::NamedValueCollection( const Any
& _rElements
)
100 :m_pImpl( new NamedValueCollection_Impl
)
102 impl_assign( _rElements
);
105 //--------------------------------------------------------------------
106 NamedValueCollection::NamedValueCollection( const Sequence
< Any
>& _rArguments
)
107 :m_pImpl( new NamedValueCollection_Impl
)
109 impl_assign( _rArguments
);
112 //--------------------------------------------------------------------
113 NamedValueCollection::NamedValueCollection( const Sequence
< PropertyValue
>& _rArguments
)
114 :m_pImpl( new NamedValueCollection_Impl
)
116 impl_assign( _rArguments
);
119 //--------------------------------------------------------------------
120 NamedValueCollection::NamedValueCollection( const Sequence
< NamedValue
>& _rArguments
)
121 :m_pImpl( new NamedValueCollection_Impl
)
123 impl_assign( _rArguments
);
126 //--------------------------------------------------------------------
127 NamedValueCollection::~NamedValueCollection()
131 //--------------------------------------------------------------------
132 NamedValueCollection
& NamedValueCollection::merge( const NamedValueCollection
& _rAdditionalValues
, bool _bOverwriteExisting
)
134 for ( NamedValueRepository::const_iterator namedValue
= _rAdditionalValues
.m_pImpl
->aValues
.begin();
135 namedValue
!= _rAdditionalValues
.m_pImpl
->aValues
.end();
139 if ( _bOverwriteExisting
|| !impl_has( namedValue
->first
) )
140 impl_put( namedValue
->first
, namedValue
->second
);
146 //--------------------------------------------------------------------
147 size_t NamedValueCollection::size() const
149 return m_pImpl
->aValues
.size();
152 //--------------------------------------------------------------------
153 bool NamedValueCollection::empty() const
155 return m_pImpl
->aValues
.empty();
158 //--------------------------------------------------------------------
159 ::std::vector
< ::rtl::OUString
> NamedValueCollection::getNames() const
161 ::std::vector
< ::rtl::OUString
> aNames( m_pImpl
->aValues
.size() );
163 m_pImpl
->aValues
.begin(),
164 m_pImpl
->aValues
.end(),
166 ::std::select1st
< NamedValueRepository::value_type
>()
171 //--------------------------------------------------------------------
172 void NamedValueCollection::impl_assign( const Any
& i_rWrappedElements
)
174 Sequence
< NamedValue
> aNamedValues
;
175 Sequence
< PropertyValue
> aPropertyValues
;
176 NamedValue aNamedValue
;
177 PropertyValue aPropertyValue
;
179 if ( i_rWrappedElements
>>= aNamedValues
)
180 impl_assign( aNamedValues
);
181 else if ( i_rWrappedElements
>>= aPropertyValues
)
182 impl_assign( aPropertyValues
);
183 else if ( i_rWrappedElements
>>= aNamedValue
)
184 impl_assign( Sequence
< NamedValue
>( &aNamedValue
, 1 ) );
185 else if ( i_rWrappedElements
>>= aPropertyValue
)
186 impl_assign( Sequence
< PropertyValue
>( &aPropertyValue
, 1 ) );
188 OSL_ENSURE( !i_rWrappedElements
.hasValue(), "NamedValueCollection::impl_assign(Any): unsupported type!" );
191 //--------------------------------------------------------------------
192 void NamedValueCollection::impl_assign( const Sequence
< Any
>& _rArguments
)
195 NamedValueRepository aEmpty
;
196 m_pImpl
->aValues
.swap( aEmpty
);
199 PropertyValue aPropertyValue
;
200 NamedValue aNamedValue
;
202 const Any
* pArgument
= _rArguments
.getConstArray();
203 const Any
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
204 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
206 if ( *pArgument
>>= aPropertyValue
)
207 m_pImpl
->aValues
[ aPropertyValue
.Name
] = aPropertyValue
.Value
;
208 else if ( *pArgument
>>= aNamedValue
)
209 m_pImpl
->aValues
[ aNamedValue
.Name
] = aNamedValue
.Value
;
210 #if OSL_DEBUG_LEVEL > 0
211 else if ( pArgument
->hasValue() )
213 ::rtl::OStringBuffer message
;
214 message
.append( "NamedValueCollection::impl_assign: encountered a value type which I cannot handle:\n" );
215 message
.append( ::rtl::OUStringToOString( pArgument
->getValueTypeName(), RTL_TEXTENCODING_ASCII_US
) );
216 OSL_ENSURE( false, message
.makeStringAndClear() );
222 //--------------------------------------------------------------------
223 void NamedValueCollection::impl_assign( const Sequence
< PropertyValue
>& _rArguments
)
226 NamedValueRepository aEmpty
;
227 m_pImpl
->aValues
.swap( aEmpty
);
230 const PropertyValue
* pArgument
= _rArguments
.getConstArray();
231 const PropertyValue
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
232 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
233 m_pImpl
->aValues
[ pArgument
->Name
] = pArgument
->Value
;
236 //--------------------------------------------------------------------
237 void NamedValueCollection::impl_assign( const Sequence
< NamedValue
>& _rArguments
)
240 NamedValueRepository aEmpty
;
241 m_pImpl
->aValues
.swap( aEmpty
);
244 const NamedValue
* pArgument
= _rArguments
.getConstArray();
245 const NamedValue
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
246 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
247 m_pImpl
->aValues
[ pArgument
->Name
] = pArgument
->Value
;
250 //--------------------------------------------------------------------
251 bool NamedValueCollection::get_ensureType( const ::rtl::OUString
& _rValueName
, void* _pValueLocation
, const Type
& _rExpectedValueType
) const
253 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
254 if ( pos
!= m_pImpl
->aValues
.end() )
256 if ( uno_type_assignData(
257 _pValueLocation
, _rExpectedValueType
.getTypeLibType(),
258 const_cast< void* >( pos
->second
.getValue() ), pos
->second
.getValueType().getTypeLibType(),
259 reinterpret_cast< uno_QueryInterfaceFunc
>( cpp_queryInterface
),
260 reinterpret_cast< uno_AcquireFunc
>( cpp_acquire
),
261 reinterpret_cast< uno_ReleaseFunc
>( cpp_release
)
263 // argument exists, and could be extracted
266 // argument exists, but is of wrong type
267 ::rtl::OUStringBuffer aBuffer
;
268 aBuffer
.appendAscii( "Invalid value type for '" );
269 aBuffer
.append ( _rValueName
);
270 aBuffer
.appendAscii( "'.\nExpected: " );
271 aBuffer
.append ( _rExpectedValueType
.getTypeName() );
272 aBuffer
.appendAscii( "\nFound: " );
273 aBuffer
.append ( pos
->second
.getValueType().getTypeName() );
274 throw IllegalArgumentException( aBuffer
.makeStringAndClear(), NULL
, 0 );
277 // argument does not exist
281 //--------------------------------------------------------------------
282 const Any
& NamedValueCollection::impl_get( const ::rtl::OUString
& _rValueName
) const
284 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
285 if ( pos
!= m_pImpl
->aValues
.end() )
288 static Any aEmptyDefault
;
289 return aEmptyDefault
;
292 //--------------------------------------------------------------------
293 bool NamedValueCollection::impl_has( const ::rtl::OUString
& _rValueName
) const
295 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
296 return ( pos
!= m_pImpl
->aValues
.end() );
299 //--------------------------------------------------------------------
300 bool NamedValueCollection::impl_put( const ::rtl::OUString
& _rValueName
, const Any
& _rValue
)
302 bool bHas
= impl_has( _rValueName
);
303 m_pImpl
->aValues
[ _rValueName
] = _rValue
;
307 //--------------------------------------------------------------------
308 bool NamedValueCollection::impl_remove( const ::rtl::OUString
& _rValueName
)
310 NamedValueRepository::iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
311 if ( pos
== m_pImpl
->aValues
.end() )
313 m_pImpl
->aValues
.erase( pos
);
317 //--------------------------------------------------------------------
320 struct Value2PropertyValue
: public ::std::unary_function
< NamedValueRepository::value_type
, PropertyValue
>
322 PropertyValue
operator()( const NamedValueRepository::value_type
& _rValue
)
324 return PropertyValue(
325 _rValue
.first
, 0, _rValue
.second
, PropertyState_DIRECT_VALUE
);
329 struct Value2NamedValue
: public ::std::unary_function
< NamedValueRepository::value_type
, NamedValue
>
331 NamedValue
operator()( const NamedValueRepository::value_type
& _rValue
)
333 return NamedValue( _rValue
.first
, _rValue
.second
);
338 //--------------------------------------------------------------------
339 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< PropertyValue
>& _out_rValues
) const
341 _out_rValues
.realloc( m_pImpl
->aValues
.size() );
342 ::std::transform( m_pImpl
->aValues
.begin(), m_pImpl
->aValues
.end(), _out_rValues
.getArray(), Value2PropertyValue() );
343 return _out_rValues
.getLength();
346 //--------------------------------------------------------------------
347 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< NamedValue
>& _out_rValues
) const
349 _out_rValues
.realloc( m_pImpl
->aValues
.size() );
350 ::std::transform( m_pImpl
->aValues
.begin(), m_pImpl
->aValues
.end(), _out_rValues
.getArray(), Value2NamedValue() );
351 return _out_rValues
.getLength();
354 //........................................................................
355 } // namespace comphelper
356 //........................................................................