merged tag ooo/OOO330_m14
[LibreOffice.git] / comphelper / source / misc / namedvaluecollection.cxx
blob8bab7fa3d7c71bbcaf2607e1f988f0da630b5f24
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 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 ) );
115 else
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();
150 ++namedValue
153 if ( _bOverwriteExisting || !impl_has( namedValue->first ) )
154 impl_put( namedValue->first, namedValue->second );
157 return *this;
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() );
199 #endif
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
245 return true;
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
259 return false;
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() )
267 return pos->second;
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;
285 return bHas;
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() )
293 return false;
294 m_pImpl->aValues.erase( pos );
295 return true;
298 //--------------------------------------------------------------------
299 namespace
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 //........................................................................