1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/namedvaluecollection.hxx>
22 #include <com/sun/star/beans/NamedValue.hpp>
23 #include <com/sun/star/lang/IllegalArgumentException.hpp>
24 #include <com/sun/star/beans/PropertyState.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
27 #include <sal/log.hxx>
30 #include <unordered_map>
36 using ::com::sun::star::uno::Any
;
37 using ::com::sun::star::uno::Sequence
;
38 using ::com::sun::star::beans::PropertyValue
;
39 using ::com::sun::star::beans::NamedValue
;
40 using ::com::sun::star::uno::Type
;
41 using ::com::sun::star::uno::cpp_acquire
;
42 using ::com::sun::star::uno::cpp_release
;
43 using ::com::sun::star::uno::cpp_queryInterface
;
44 using ::com::sun::star::lang::IllegalArgumentException
;
45 using ::com::sun::star::beans::PropertyState_DIRECT_VALUE
;
47 NamedValueCollection::NamedValueCollection( const Any
& _rElements
)
49 impl_assign( _rElements
);
53 NamedValueCollection::NamedValueCollection( const Sequence
< Any
>& _rArguments
)
55 impl_assign( _rArguments
);
59 NamedValueCollection::NamedValueCollection( const Sequence
< PropertyValue
>& _rArguments
)
61 impl_assign( _rArguments
);
65 NamedValueCollection::NamedValueCollection( const Sequence
< NamedValue
>& _rArguments
)
67 impl_assign( _rArguments
);
71 bool NamedValueCollection::canExtractFrom( css::uno::Any
const & i_value
)
73 Type
const & aValueType
= i_value
.getValueType();
74 return aValueType
.equals( ::cppu::UnoType
< PropertyValue
>::get() )
75 || aValueType
.equals( ::cppu::UnoType
< NamedValue
>::get() )
76 || aValueType
.equals( ::cppu::UnoType
< Sequence
< PropertyValue
> >::get() )
77 || aValueType
.equals( ::cppu::UnoType
< Sequence
< NamedValue
> >::get() );
81 NamedValueCollection
& NamedValueCollection::merge( const NamedValueCollection
& _rAdditionalValues
, bool _bOverwriteExisting
)
83 for (auto const& value
: _rAdditionalValues
.maValues
)
85 if ( _bOverwriteExisting
|| !impl_has( value
.first
) )
86 impl_put( value
.first
, value
.second
);
93 size_t NamedValueCollection::size() const
95 return maValues
.size();
99 bool NamedValueCollection::empty() const
101 return maValues
.empty();
105 std::vector
< OUString
> NamedValueCollection::getNames() const
107 std::vector
< OUString
> aNames
;
108 for (auto const& value
: maValues
)
110 aNames
.push_back( value
.first
);
116 void NamedValueCollection::impl_assign( const Any
& i_rWrappedElements
)
118 Sequence
< NamedValue
> aNamedValues
;
119 Sequence
< PropertyValue
> aPropertyValues
;
120 NamedValue aNamedValue
;
121 PropertyValue aPropertyValue
;
123 if ( i_rWrappedElements
>>= aNamedValues
)
124 impl_assign( aNamedValues
);
125 else if ( i_rWrappedElements
>>= aPropertyValues
)
126 impl_assign( aPropertyValues
);
127 else if ( i_rWrappedElements
>>= aNamedValue
)
128 impl_assign( Sequence
< NamedValue
>( &aNamedValue
, 1 ) );
129 else if ( i_rWrappedElements
>>= aPropertyValue
)
130 impl_assign( Sequence
< PropertyValue
>( &aPropertyValue
, 1 ) );
132 SAL_WARN_IF( i_rWrappedElements
.hasValue(), "comphelper", "NamedValueCollection::impl_assign(Any): unsupported type!" );
136 void NamedValueCollection::impl_assign( const Sequence
< Any
>& _rArguments
)
140 PropertyValue aPropertyValue
;
141 NamedValue aNamedValue
;
143 for ( auto const & argument
: _rArguments
)
145 if ( argument
>>= aPropertyValue
)
146 maValues
[ aPropertyValue
.Name
] = aPropertyValue
.Value
;
147 else if ( argument
>>= aNamedValue
)
148 maValues
[ aNamedValue
.Name
] = aNamedValue
.Value
;
152 argument
.hasValue(), "comphelper",
153 ("NamedValueCollection::impl_assign: encountered a value"
154 " type which I cannot handle: "
155 + argument
.getValueTypeName()));
161 void NamedValueCollection::impl_assign( const Sequence
< PropertyValue
>& _rArguments
)
165 for ( auto const & argument
: _rArguments
)
166 maValues
[ argument
.Name
] = argument
.Value
;
170 void NamedValueCollection::impl_assign( const Sequence
< NamedValue
>& _rArguments
)
174 for ( auto const & argument
: _rArguments
)
175 maValues
[ argument
.Name
] = argument
.Value
;
179 bool NamedValueCollection::get_ensureType( const OUString
& _rValueName
, void* _pValueLocation
, const Type
& _rExpectedValueType
) const
181 auto pos
= maValues
.find( _rValueName
);
182 if ( pos
== maValues
.end() )
183 // argument does not exist
186 if ( uno_type_assignData(
187 _pValueLocation
, _rExpectedValueType
.getTypeLibType(),
188 const_cast< void* >( pos
->second
.getValue() ), pos
->second
.getValueType().getTypeLibType(),
189 reinterpret_cast< uno_QueryInterfaceFunc
>( cpp_queryInterface
),
190 reinterpret_cast< uno_AcquireFunc
>( cpp_acquire
),
191 reinterpret_cast< uno_ReleaseFunc
>( cpp_release
)
193 // argument exists, and could be extracted
196 // argument exists, but is of wrong type
197 throw IllegalArgumentException(
198 "Invalid value type for '" + _rValueName
199 + "'.\nExpected: " + _rExpectedValueType
.getTypeName()
200 + "\nFound: " + pos
->second
.getValueType().getTypeName(),
205 bool NamedValueCollection::get_ensureType( const css::uno::Sequence
<css::beans::PropertyValue
>& rPropSeq
,
206 std::u16string_view _rValueName
, void* _pValueLocation
, const Type
& _rExpectedValueType
)
208 for (const css::beans::PropertyValue
& rPropVal
: rPropSeq
)
210 if (rPropVal
.Name
== _rValueName
)
212 if ( uno_type_assignData(
213 _pValueLocation
, _rExpectedValueType
.getTypeLibType(),
214 const_cast< void* >( rPropVal
.Value
.getValue() ), rPropVal
.Value
.getValueType().getTypeLibType(),
215 reinterpret_cast< uno_QueryInterfaceFunc
>( cpp_queryInterface
),
216 reinterpret_cast< uno_AcquireFunc
>( cpp_acquire
),
217 reinterpret_cast< uno_ReleaseFunc
>( cpp_release
)
219 // argument exists, and could be extracted
222 // argument exists, but is of wrong type
223 throw IllegalArgumentException(
224 OUString::Concat("Invalid value type for '") + _rValueName
225 + "'.\nExpected: " + _rExpectedValueType
.getTypeName()
226 + "\nFound: " + rPropVal
.Value
.getValueType().getTypeName(),
230 // argument does not exist
235 const css::uno::Any
& NamedValueCollection::get( const css::uno::Sequence
<css::beans::PropertyValue
>& rPropSeq
,
236 std::u16string_view _rValueName
)
238 static const Any theEmptyDefault
;
239 for (const css::beans::PropertyValue
& rPropVal
: rPropSeq
)
241 if (rPropVal
.Name
== _rValueName
)
243 return rPropVal
.Value
;
246 return theEmptyDefault
;
249 const Any
& NamedValueCollection::impl_get( const OUString
& _rValueName
) const
251 static const Any theEmptyDefault
;
252 auto pos
= maValues
.find( _rValueName
);
253 if ( pos
!= maValues
.end() )
256 return theEmptyDefault
;
260 bool NamedValueCollection::impl_has( const OUString
& _rValueName
) const
262 auto pos
= maValues
.find( _rValueName
);
263 return ( pos
!= maValues
.end() );
267 bool NamedValueCollection::impl_put( const OUString
& _rValueName
, const Any
& _rValue
)
269 bool bHas
= impl_has( _rValueName
);
270 maValues
[ _rValueName
] = _rValue
;
275 bool NamedValueCollection::impl_remove( const OUString
& _rValueName
)
277 auto pos
= maValues
.find( _rValueName
);
278 if ( pos
== maValues
.end() )
280 maValues
.erase( pos
);
285 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< PropertyValue
>& _out_rValues
) const
287 _out_rValues
.realloc( maValues
.size() );
288 std::transform( maValues
.begin(), maValues
.end(), _out_rValues
.getArray(),
289 [](const std::pair
< OUString
, css::uno::Any
>& _rValue
)
290 { return PropertyValue( _rValue
.first
, 0, _rValue
.second
, PropertyState_DIRECT_VALUE
); } );
291 return _out_rValues
.getLength();
295 sal_Int32
NamedValueCollection::operator >>= ( Sequence
< NamedValue
>& _out_rValues
) const
297 _out_rValues
.realloc( maValues
.size() );
298 std::transform( maValues
.begin(), maValues
.end(), _out_rValues
.getArray(),
299 [](const std::pair
< OUString
, css::uno::Any
>& _rValue
)
300 { return NamedValue( _rValue
.first
, _rValue
.second
); } );
301 return _out_rValues
.getLength();
305 } // namespace comphelper
308 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */