CWS-TOOLING: integrate CWS os146
[LibreOffice.git] / comphelper / source / misc / namedvaluecollection.cxx
blob566e5526019c37e396e662c2bb84c4ebb0ab7d48
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>
42 #include <hash_map>
43 #include <functional>
44 #include <algorithm>
46 //........................................................................
47 namespace comphelper
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 )
88 *this = _rCopySource;
91 //--------------------------------------------------------------------
92 NamedValueCollection& NamedValueCollection::operator=( const NamedValueCollection& i_rCopySource )
94 m_pImpl->aValues = i_rCopySource.m_pImpl->aValues;
95 return *this;
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();
136 ++namedValue
139 if ( _bOverwriteExisting || !impl_has( namedValue->first ) )
140 impl_put( namedValue->first, namedValue->second );
143 return *this;
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() );
162 ::std::transform(
163 m_pImpl->aValues.begin(),
164 m_pImpl->aValues.end(),
165 aNames.begin(),
166 ::std::select1st< NamedValueRepository::value_type >()
168 return aNames;
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 ) );
187 else
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() );
218 #endif
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
264 return true;
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
278 return false;
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() )
286 return pos->second;
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;
304 return bHas;
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() )
312 return false;
313 m_pImpl->aValues.erase( pos );
314 return true;
317 //--------------------------------------------------------------------
318 namespace
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 //........................................................................