LibreOffice Module comphelper (master) 1
namedvaluecollection.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
21
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>
26
27#include <sal/log.hxx>
28
29#include <algorithm>
30#include <unordered_map>
31
32namespace comphelper
33{
34
35
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;
46
47 NamedValueCollection::NamedValueCollection( const Any& _rElements )
48 {
49 impl_assign( _rElements );
50 }
51
52
53 NamedValueCollection::NamedValueCollection( const Sequence< Any >& _rArguments )
54 {
55 impl_assign( _rArguments );
56 }
57
58
59 NamedValueCollection::NamedValueCollection( const Sequence< PropertyValue >& _rArguments )
60 {
61 impl_assign( _rArguments );
62 }
63
64
65 NamedValueCollection::NamedValueCollection( const Sequence< NamedValue >& _rArguments )
66 {
67 impl_assign( _rArguments );
68 }
69
70
71 bool NamedValueCollection::canExtractFrom( css::uno::Any const & i_value )
72 {
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() );
78 }
79
80
81 NamedValueCollection& NamedValueCollection::merge( const NamedValueCollection& _rAdditionalValues, bool _bOverwriteExisting )
82 {
83 for (auto const& value : _rAdditionalValues.maValues)
84 {
85 if ( _bOverwriteExisting || !impl_has( value.first ) )
86 impl_put( value.first, value.second );
87 }
88
89 return *this;
90 }
91
92
94 {
95 return maValues.size();
96 }
97
98
100 {
101 return maValues.empty();
102 }
103
104
105 std::vector< OUString > NamedValueCollection::getNames() const
106 {
107 std::vector< OUString > aNames;
108 for (auto const& value : maValues)
109 {
110 aNames.push_back( value.first );
111 }
112 return aNames;
113 }
114
115
116 void NamedValueCollection::impl_assign( const Any& i_rWrappedElements )
117 {
118 Sequence< NamedValue > aNamedValues;
119 Sequence< PropertyValue > aPropertyValues;
120 NamedValue aNamedValue;
121 PropertyValue aPropertyValue;
122
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 ) );
131 else
132 SAL_WARN_IF( i_rWrappedElements.hasValue(), "comphelper", "NamedValueCollection::impl_assign(Any): unsupported type!" );
133 }
134
135
136 void NamedValueCollection::impl_assign( const Sequence< Any >& _rArguments )
137 {
138 maValues.clear();
139
140 PropertyValue aPropertyValue;
141 NamedValue aNamedValue;
142
143 for ( auto const & argument : _rArguments )
144 {
145 if ( argument >>= aPropertyValue )
146 maValues[ aPropertyValue.Name ] = aPropertyValue.Value;
147 else if ( argument >>= aNamedValue )
148 maValues[ aNamedValue.Name ] = aNamedValue.Value;
149 else
150 {
152 argument.hasValue(), "comphelper",
153 ("NamedValueCollection::impl_assign: encountered a value"
154 " type which I cannot handle: "
155 + argument.getValueTypeName()));
156 }
157 }
158 }
159
160
161 void NamedValueCollection::impl_assign( const Sequence< PropertyValue >& _rArguments )
162 {
163 maValues.clear();
164
165 for ( auto const & argument : _rArguments )
166 maValues[ argument.Name ] = argument.Value;
167 }
168
169
170 void NamedValueCollection::impl_assign( const Sequence< NamedValue >& _rArguments )
171 {
172 maValues.clear();
173
174 for ( auto const & argument : _rArguments )
175 maValues[ argument.Name ] = argument.Value;
176 }
177
178
179 bool NamedValueCollection::get_ensureType( const OUString& _rValueName, void* _pValueLocation, const Type& _rExpectedValueType ) const
180 {
181 auto pos = maValues.find( _rValueName );
182 if ( pos == maValues.end() )
183 // argument does not exist
184 return false;
185
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 )
192 ) )
193 // argument exists, and could be extracted
194 return true;
195
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(),
201 nullptr, 0 );
202 }
203
204 // static
205 bool NamedValueCollection::get_ensureType( const css::uno::Sequence<css::beans::PropertyValue>& rPropSeq,
206 std::u16string_view _rValueName, void* _pValueLocation, const Type& _rExpectedValueType )
207 {
208 for (const css::beans::PropertyValue& rPropVal : rPropSeq)
209 {
210 if (rPropVal.Name == _rValueName)
211 {
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 )
218 ) )
219 // argument exists, and could be extracted
220 return true;
221
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(),
227 nullptr, 0 );
228 }
229 }
230 // argument does not exist
231 return false;
232 }
233
234 // static
235 const css::uno::Any& NamedValueCollection::get( const css::uno::Sequence<css::beans::PropertyValue>& rPropSeq,
236 std::u16string_view _rValueName )
237 {
238 static const Any theEmptyDefault;
239 for (const css::beans::PropertyValue& rPropVal : rPropSeq)
240 {
241 if (rPropVal.Name == _rValueName)
242 {
243 return rPropVal.Value;
244 }
245 }
246 return theEmptyDefault;
247 }
248
249 const Any& NamedValueCollection::impl_get( const OUString& _rValueName ) const
250 {
251 static const Any theEmptyDefault;
252 auto pos = maValues.find( _rValueName );
253 if ( pos != maValues.end() )
254 return pos->second;
255
256 return theEmptyDefault;
257 }
258
259
260 bool NamedValueCollection::impl_has( const OUString& _rValueName ) const
261 {
262 auto pos = maValues.find( _rValueName );
263 return ( pos != maValues.end() );
264 }
265
266
267 bool NamedValueCollection::impl_put( const OUString& _rValueName, const Any& _rValue )
268 {
269 bool bHas = impl_has( _rValueName );
270 maValues[ _rValueName ] = _rValue;
271 return bHas;
272 }
273
274
275 bool NamedValueCollection::impl_remove( const OUString& _rValueName )
276 {
277 auto pos = maValues.find( _rValueName );
278 if ( pos == maValues.end() )
279 return false;
280 maValues.erase( pos );
281 return true;
282 }
283
284
285 sal_Int32 NamedValueCollection::operator >>= ( Sequence< PropertyValue >& _out_rValues ) const
286 {
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();
292 }
293
294
295 sal_Int32 NamedValueCollection::operator >>= ( Sequence< NamedValue >& _out_rValues ) const
296 {
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();
302 }
303
304
305} // namespace comphelper
306
307
308/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::boost::spirit::classic::rule< ScannerT > argument
PropertyValueVector_t aPropertyValues
a collection of named values, packed in various formats.
bool get_ensureType(const OUString &_rValueName, VALUE_TYPE &_out_rValue) const
retrieves a value with a given name from the collection, if it is present
const css::uno::Any & get(const OUString &_rValueName) const
retrieves a (untyped) value with a given name
static bool canExtractFrom(css::uno::Any const &i_value)
determines whether or not named values can be extracted from the given value
bool impl_put(const OUString &_rValueName, const css::uno::Any &_rValue)
bool impl_has(const OUString &_rValueName) const
void impl_assign(const css::uno::Any &i_rWrappedElements)
const css::uno::Any & impl_get(const OUString &_rValueName) const
std::unordered_map< OUString, css::uno::Any > maValues
NamedValueCollection & merge(const NamedValueCollection &_rAdditionalValues, bool _bOverwriteExisting)
merges the content of another collection into this
bool empty() const
determines whether the collection is empty
bool impl_remove(const OUString &_rValueName)
size_t size() const
returns the number of elements in the collection
sal_Int32 operator>>=(css::uno::Sequence< css::beans::PropertyValue > &_out_rValues) const
transforms the collection to a sequence of PropertyValues
::std::vector< OUString > getNames() const
returns the names of all elements in the collection
Any value
sal_Bool SAL_CALL uno_type_assignData(void *pDest, typelib_TypeDescriptionReference *pDestType, void *pSource, typelib_TypeDescriptionReference *pSourceType, uno_QueryInterfaceFunc queryInterface, uno_AcquireFunc acquire, uno_ReleaseFunc release) SAL_THROW_EXTERN_C()
#define SAL_WARN_IF(condition, area, stream)
Type
size_t pos