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 Sequence
< NamedValue
> aNamedValues
;
103 Sequence
< PropertyValue
> aPropertyValues
;
104 NamedValue aNamedValue
;
105 PropertyValue aPropertyValue
;
107 if ( _rElements
>>= aNamedValues
)
108 impl_assign( aNamedValues
);
109 else if ( _rElements
>>= aPropertyValues
)
110 impl_assign( aPropertyValues
);
111 else if ( _rElements
>>= aNamedValue
)
112 impl_assign( Sequence
< NamedValue
>( &aNamedValue
, 1 ) );
113 else if ( _rElements
>>= aPropertyValue
)
114 impl_assign( Sequence
< PropertyValue
>( &aPropertyValue
, 1 ) );
116 OSL_ENSURE( !_rElements
.hasValue(), "NamedValueCollection::NamedValueCollection(Any): unsupported type!" );
119 //--------------------------------------------------------------------
120 NamedValueCollection::NamedValueCollection( const Sequence
< Any
>& _rArguments
)
121 :m_pImpl( new NamedValueCollection_Impl
)
123 impl_assign( _rArguments
);
126 //--------------------------------------------------------------------
127 NamedValueCollection::NamedValueCollection( const Sequence
< PropertyValue
>& _rArguments
)
128 :m_pImpl( new NamedValueCollection_Impl
)
130 impl_assign( _rArguments
);
133 //--------------------------------------------------------------------
134 NamedValueCollection::NamedValueCollection( const Sequence
< NamedValue
>& _rArguments
)
135 :m_pImpl( new NamedValueCollection_Impl
)
137 impl_assign( _rArguments
);
140 //--------------------------------------------------------------------
141 NamedValueCollection::~NamedValueCollection()
145 //--------------------------------------------------------------------
146 NamedValueCollection
& NamedValueCollection::merge( const NamedValueCollection
& _rAdditionalValues
, bool _bOverwriteExisting
)
148 for ( NamedValueRepository::const_iterator namedValue
= _rAdditionalValues
.m_pImpl
->aValues
.begin();
149 namedValue
!= _rAdditionalValues
.m_pImpl
->aValues
.end();
153 if ( _bOverwriteExisting
|| !impl_has( namedValue
->first
) )
154 impl_put( namedValue
->first
, namedValue
->second
);
160 //--------------------------------------------------------------------
161 size_t NamedValueCollection::size() const
163 return m_pImpl
->aValues
.size();
166 //--------------------------------------------------------------------
167 bool NamedValueCollection::empty() const
169 return m_pImpl
->aValues
.empty();
172 //--------------------------------------------------------------------
173 void NamedValueCollection::impl_assign( const Sequence
< Any
>& _rArguments
)
176 NamedValueRepository aEmpty
;
177 m_pImpl
->aValues
.swap( aEmpty
);
180 PropertyValue aPropertyValue
;
181 NamedValue aNamedValue
;
183 const Any
* pArgument
= _rArguments
.getConstArray();
184 const Any
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
185 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
187 if ( *pArgument
>>= aPropertyValue
)
188 m_pImpl
->aValues
[ aPropertyValue
.Name
] = aPropertyValue
.Value
;
189 else if ( *pArgument
>>= aNamedValue
)
190 m_pImpl
->aValues
[ aNamedValue
.Name
] = aNamedValue
.Value
;
191 #if OSL_DEBUG_LEVEL > 0
192 else if ( pArgument
->hasValue() )
194 ::rtl::OStringBuffer message
;
195 message
.append( "NamedValueCollection::impl_assign: encountered a value type which I cannot handle:\n" );
196 message
.append( ::rtl::OUStringToOString( pArgument
->getValueTypeName(), RTL_TEXTENCODING_ASCII_US
) );
197 OSL_ENSURE( false, message
.makeStringAndClear() );
203 //--------------------------------------------------------------------
204 void NamedValueCollection::impl_assign( const Sequence
< PropertyValue
>& _rArguments
)
207 NamedValueRepository aEmpty
;
208 m_pImpl
->aValues
.swap( aEmpty
);
211 const PropertyValue
* pArgument
= _rArguments
.getConstArray();
212 const PropertyValue
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
213 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
214 m_pImpl
->aValues
[ pArgument
->Name
] = pArgument
->Value
;
217 //--------------------------------------------------------------------
218 void NamedValueCollection::impl_assign( const Sequence
< NamedValue
>& _rArguments
)
221 NamedValueRepository aEmpty
;
222 m_pImpl
->aValues
.swap( aEmpty
);
225 const NamedValue
* pArgument
= _rArguments
.getConstArray();
226 const NamedValue
* pArgumentEnd
= _rArguments
.getConstArray() + _rArguments
.getLength();
227 for ( ; pArgument
!= pArgumentEnd
; ++pArgument
)
228 m_pImpl
->aValues
[ pArgument
->Name
] = pArgument
->Value
;
231 //--------------------------------------------------------------------
232 bool NamedValueCollection::get_ensureType( const ::rtl::OUString
& _rValueName
, void* _pValueLocation
, const Type
& _rExpectedValueType
) const
234 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
235 if ( pos
!= m_pImpl
->aValues
.end() )
237 if ( uno_type_assignData(
238 _pValueLocation
, _rExpectedValueType
.getTypeLibType(),
239 const_cast< void* >( pos
->second
.getValue() ), pos
->second
.getValueType().getTypeLibType(),
240 reinterpret_cast< uno_QueryInterfaceFunc
>( cpp_queryInterface
),
241 reinterpret_cast< uno_AcquireFunc
>( cpp_acquire
),
242 reinterpret_cast< uno_ReleaseFunc
>( cpp_release
)
244 // argument exists, and could be extracted
247 // argument exists, but is of wrong type
248 ::rtl::OUStringBuffer aBuffer
;
249 aBuffer
.appendAscii( "Invalid value type for '" );
250 aBuffer
.append ( _rValueName
);
251 aBuffer
.appendAscii( "'.\nExpected: " );
252 aBuffer
.append ( _rExpectedValueType
.getTypeName() );
253 aBuffer
.appendAscii( "\nFound: " );
254 aBuffer
.append ( pos
->second
.getValueType().getTypeName() );
255 throw IllegalArgumentException( aBuffer
.makeStringAndClear(), NULL
, 0 );
258 // argument does not exist
262 //--------------------------------------------------------------------
263 const Any
& NamedValueCollection::impl_get( const ::rtl::OUString
& _rValueName
) const
265 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
266 if ( pos
!= m_pImpl
->aValues
.end() )
269 static Any aEmptyDefault
;
270 return aEmptyDefault
;
273 //--------------------------------------------------------------------
274 bool NamedValueCollection::impl_has( const ::rtl::OUString
& _rValueName
) const
276 NamedValueRepository::const_iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
277 return ( pos
!= m_pImpl
->aValues
.end() );
280 //--------------------------------------------------------------------
281 bool NamedValueCollection::impl_put( const ::rtl::OUString
& _rValueName
, const Any
& _rValue
)
283 bool bHas
= impl_has( _rValueName
);
284 m_pImpl
->aValues
[ _rValueName
] = _rValue
;
288 //--------------------------------------------------------------------
289 bool NamedValueCollection::impl_remove( const ::rtl::OUString
& _rValueName
)
291 NamedValueRepository::iterator pos
= m_pImpl
->aValues
.find( _rValueName
);
292 if ( pos
== m_pImpl
->aValues
.end() )
294 m_pImpl
->aValues
.erase( pos
);
298 //--------------------------------------------------------------------
301 struct Value2PropertyValue
: public ::std::unary_function
< NamedValueRepository::value_type
, PropertyValue
>
303 PropertyValue
operator()( const NamedValueRepository::value_type
& _rValue
)
305 return PropertyValue(
306 _rValue
.first
, 0, _rValue
.second
, PropertyState_DIRECT_VALUE
);
310 struct Value2NamedValue
: public ::std::unary_function
< NamedValueRepository::value_type
, NamedValue
>
312 NamedValue
operator()( const NamedValueRepository::value_type
& _rValue
)
314 return NamedValue( _rValue
.first
, _rValue
.second
);
319 //--------------------------------------------------------------------
320 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< PropertyValue
>& _out_rValues
) const
322 _out_rValues
.realloc( m_pImpl
->aValues
.size() );
323 ::std::transform( m_pImpl
->aValues
.begin(), m_pImpl
->aValues
.end(), _out_rValues
.getArray(), Value2PropertyValue() );
324 return _out_rValues
.getLength();
327 //--------------------------------------------------------------------
328 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< NamedValue
>& _out_rValues
) const
330 _out_rValues
.realloc( m_pImpl
->aValues
.size() );
331 ::std::transform( m_pImpl
->aValues
.begin(), m_pImpl
->aValues
.end(), _out_rValues
.getArray(), Value2NamedValue() );
332 return _out_rValues
.getLength();
335 //........................................................................
336 } // namespace comphelper
337 //........................................................................