1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef COMPHELPER_NAMEDVALUECOLLECTION_HXX
25 #define COMPHELPER_NAMEDVALUECOLLECTION_HXX
26 
27 #include <comphelper/comphelperdllapi.h>
28 
29 /** === begin UNO includes === **/
30 #include <com/sun/star/uno/Sequence.hxx>
31 #include <com/sun/star/uno/Any.hxx>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/beans/NamedValue.hpp>
34 /** === end UNO includes === **/
35 
36 #include <memory>
37 #include <algorithm>
38 #include <vector>
39 
40 //........................................................................
41 namespace comphelper
42 {
43 //........................................................................
44 
45 	// ====================================================================
46 	// = NamedValueCollection
47 	// ====================================================================
48     struct NamedValueCollection_Impl;
49     /** a collection of named values, packed in various formats.
50     */
51     class COMPHELPER_DLLPUBLIC NamedValueCollection
52     {
53     private:
54         ::std::auto_ptr< NamedValueCollection_Impl >    m_pImpl;
55 
56     public:
57         NamedValueCollection();
58 
59         NamedValueCollection( const NamedValueCollection& _rCopySource );
60 
61         NamedValueCollection& operator=( const NamedValueCollection& i_rCopySource );
62 
63         /** constructs a collection
64             @param  _rElements
65                 the wrapped elements of the collection. The <code>Any</code> might contain a sequence of
66                 property values, a sequence of named values, or directly a property value or named value.
67                 All other cases are worth an assertion in non-product builds.
68         */
69         NamedValueCollection( const ::com::sun::star::uno::Any& _rElements );
70 
71         /** constructs a collection
72             @param _rArguments
73                 a sequence of Any's containing either PropertyValue's or NamedValue's.
74         */
75         NamedValueCollection( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments );
76 
77         /** constructs a collection
78             @param _rArguments
79                 a sequence of PropertyValues's
80         */
81         NamedValueCollection( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments );
82 
83         /** constructs a collection
84             @param _rArguments
85                 a sequence of NamedValue's
86         */
87         NamedValueCollection( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rArguments );
88 
89         ~NamedValueCollection();
90 
assign(const::com::sun::star::uno::Any & i_rWrappedElements)91         inline void assign( const ::com::sun::star::uno::Any& i_rWrappedElements )
92         {
93             impl_assign( i_rWrappedElements );
94         }
95 
assign(const::com::sun::star::uno::Sequence<::com::sun::star::uno::Any> & _rArguments)96         inline void assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments )
97         {
98             impl_assign( _rArguments );
99         }
100 
assign(const::com::sun::star::uno::Sequence<::com::sun::star::beans::PropertyValue> & _rArguments)101         inline void assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments )
102         {
103             impl_assign( _rArguments );
104         }
105 
assign(const::com::sun::star::uno::Sequence<::com::sun::star::beans::NamedValue> & _rArguments)106         inline void assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rArguments )
107         {
108             impl_assign( _rArguments );
109         }
110 
clear()111         inline void clear()
112         {
113             impl_assign( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >() );
114         }
115 
116         /** determines whether or not named values can be extracted from the given value
117 
118             @return
119                 <TRUE/> if and only if the given <code>Any</code> contains a <code>NamedValue</code>, a
120                 <code>PropertyValue</code>, or a sequence thereof.
121         */
122         static bool canExtractFrom( ::com::sun::star::uno::Any const & i_value );
123 
124         /// returns the number of elements in the collection
125         size_t  size() const;
126 
127         /// determines whether the collection is empty
128         bool    empty() const;
129 
130         /** returns the names of all elements in the collection
131         */
132         ::std::vector< ::rtl::OUString >
133                 getNames() const;
134 
135         /** merges the content of another collection into |this|
136             @param _rAdditionalValues
137                 the collection whose values are to be merged
138             @param _bOverwriteExisting
139                 defines whether or not elements which are already present in |this|
140                 should be overwritten (<TRUE/>) or preserved (<FALSE/>).
141             @return |*this|
142         */
143         NamedValueCollection&
144                 merge(
145                     const NamedValueCollection& _rAdditionalValues,
146                     bool _bOverwriteExisting
147                 );
148 
149         /** retrieves a value with a given name from the collection, if it is present
150 
151             @param _pAsciiValueName
152                 the ASCII name of the value to retrieve
153 
154             @param _out_rValue
155                 is the output parameter taking the desired value upon successful return. If
156                 a value with the given name is not present in the collection, or if a wrong-typed
157                 value is present, then this parameter will not be touched.
158 
159             @return
160                 <TRUE/> if there is a value with the given name, which could successfully
161                 be extracted. In this case, <arg>_out_rValue</arg> will contain the requested
162                 value.<br/>
163                 <FALSE/>, if there is no value with the given name.
164             @throws IllegalArgumentException
165                 in case there is a value with the given name, but it cannot legally assigned to
166                 _out_rValue.
167         */
168         template < typename VALUE_TYPE >
get_ensureType(const sal_Char * _pAsciiValueName,VALUE_TYPE & _out_rValue) const169         bool get_ensureType( const sal_Char* _pAsciiValueName, VALUE_TYPE& _out_rValue ) const
170         {
171             return get_ensureType( ::rtl::OUString::createFromAscii( _pAsciiValueName ), &_out_rValue, ::cppu::UnoType< VALUE_TYPE >::get() );
172         }
173 
174         template < typename VALUE_TYPE >
get_ensureType(const::rtl::OUString & _rValueName,VALUE_TYPE & _out_rValue) const175         bool    get_ensureType( const ::rtl::OUString& _rValueName, VALUE_TYPE& _out_rValue ) const
176         {
177             return get_ensureType( _rValueName, &_out_rValue, ::cppu::UnoType< VALUE_TYPE >::get() );
178         }
179 
180         /** retrieves a value with a given name, or defaults it to a given value, if its not present
181             in the collection
182         */
183         template < typename VALUE_TYPE >
getOrDefault(const sal_Char * _pAsciiValueName,const VALUE_TYPE & _rDefault) const184         VALUE_TYPE  getOrDefault( const sal_Char* _pAsciiValueName, const VALUE_TYPE& _rDefault ) const
185         {
186             return getOrDefault( ::rtl::OUString::createFromAscii( _pAsciiValueName ), _rDefault );
187         }
188 
189         template < typename VALUE_TYPE >
getOrDefault(const::rtl::OUString & _rValueName,const VALUE_TYPE & _rDefault) const190         VALUE_TYPE  getOrDefault( const ::rtl::OUString& _rValueName, const VALUE_TYPE& _rDefault ) const
191         {
192             VALUE_TYPE retVal( _rDefault );
193             get_ensureType( _rValueName, retVal );
194             return retVal;
195         }
196 
197         /** retrieves a (untyped) value with a given name
198 
199             If the collection does not contain a value with the given name, an empty
200             Any is returned.
201         */
get(const sal_Char * _pAsciiValueName) const202         const ::com::sun::star::uno::Any& get( const sal_Char* _pAsciiValueName ) const
203         {
204             return get( ::rtl::OUString::createFromAscii( _pAsciiValueName ) );
205         }
206 
207         /** retrieves a (untyped) value with a given name
208 
209             If the collection does not contain a value with the given name, an empty
210             Any is returned.
211         */
get(const::rtl::OUString & _rValueName) const212         const ::com::sun::star::uno::Any& get( const ::rtl::OUString& _rValueName ) const
213         {
214             return impl_get( _rValueName );
215         }
216 
217         /// determines whether a value with a given name is present in the collection
has(const sal_Char * _pAsciiValueName) const218         inline bool has( const sal_Char* _pAsciiValueName ) const
219         {
220             return impl_has( ::rtl::OUString::createFromAscii( _pAsciiValueName ) );
221         }
222 
223         /// determines whether a value with a given name is present in the collection
has(const::rtl::OUString & _rValueName) const224         inline bool has( const ::rtl::OUString& _rValueName ) const
225         {
226             return impl_has( _rValueName );
227         }
228 
229         /** puts a value into the collection
230 
231             @return <TRUE/> if and only if a value was already present previously, in
232                 which case it has been overwritten.
233         */
234         template < typename VALUE_TYPE >
put(const sal_Char * _pAsciiValueName,const VALUE_TYPE & _rValue)235         inline bool put( const sal_Char* _pAsciiValueName, const VALUE_TYPE& _rValue )
236         {
237             return impl_put( ::rtl::OUString::createFromAscii( _pAsciiValueName ), ::com::sun::star::uno::makeAny( _rValue ) );
238         }
239 
240         /** puts a value into the collection
241 
242             @return <TRUE/> if and only if a value was already present previously, in
243                 which case it has been overwritten.
244         */
245         template < typename VALUE_TYPE >
put(const::rtl::OUString & _rValueName,const VALUE_TYPE & _rValue)246         inline bool put( const ::rtl::OUString& _rValueName, const VALUE_TYPE& _rValue )
247         {
248             return impl_put( _rValueName, ::com::sun::star::uno::makeAny( _rValue ) );
249         }
250 
put(const sal_Char * _pAsciiValueName,const::com::sun::star::uno::Any & _rValue)251         inline bool put( const sal_Char* _pAsciiValueName, const ::com::sun::star::uno::Any& _rValue )
252         {
253             return impl_put( ::rtl::OUString::createFromAscii( _pAsciiValueName ), _rValue );
254         }
255 
put(const::rtl::OUString & _rValueName,const::com::sun::star::uno::Any & _rValue)256         inline bool put( const ::rtl::OUString& _rValueName, const ::com::sun::star::uno::Any& _rValue )
257         {
258             return impl_put( _rValueName, _rValue );
259         }
260 
261         /** removes the value with the given name from the collection
262 
263             @return <TRUE/> if and only if a value with the given name existed in the collection.
264         */
remove(const sal_Char * _pAsciiValueName)265         inline bool remove( const sal_Char* _pAsciiValueName )
266         {
267             return impl_remove( ::rtl::OUString::createFromAscii( _pAsciiValueName ) );
268         }
269 
270         /** removes the value with the given name from the collection
271 
272             @return <TRUE/> if and only if a value with the given name existed in the collection.
273         */
remove(const::rtl::OUString & _rValueName)274         inline bool remove( const ::rtl::OUString& _rValueName )
275         {
276             return impl_remove( _rValueName );
277         }
278 
279         /** transforms the collection to a sequence of PropertyValues
280 
281             @return
282                 the  number of elements in the sequence
283         */
284         sal_Int32 operator >>= ( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _out_rValues ) const;
285 
286         /** transforms the collection to a sequence of NamedValues
287 
288             @return
289                 the  number of elements in the sequence
290         */
291         sal_Int32 operator >>= ( ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _out_rValues ) const;
292 
293         /** transforms the collection into a sequence of PropertyValues
294         */
295         inline ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >
getPropertyValues() const296                 getPropertyValues() const
297         {
298             ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues;
299             *this >>= aValues;
300             return aValues;
301         }
302 
303         /** returns a Sequence< Any >, containing PropertyValues
304         */
305         inline ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
getWrappedPropertyValues() const306                 getWrappedPropertyValues() const
307         {
308             return impl_wrap< ::com::sun::star::beans::PropertyValue >();
309         }
310 
311         /** returns a Sequence< Any >, containing NamedValues
312         */
313         inline ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
getWrappedNamedValues() const314                 getWrappedNamedValues() const
315         {
316             return impl_wrap< ::com::sun::star::beans::NamedValue >();
317         }
318 
319         /** transforms the collection into a sequence of NamedValues
320         */
321         inline ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >
getNamedValues() const322                 getNamedValues() const
323         {
324             ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > aValues;
325             *this >>= aValues;
326             return aValues;
327         }
328 
329     private:
330         void    impl_assign( const ::com::sun::star::uno::Any& i_rWrappedElements );
331         void    impl_assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rArguments );
332         void    impl_assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& _rArguments );
333         void    impl_assign( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue >& _rArguments );
334 
335         bool    get_ensureType(
336                     const ::rtl::OUString& _rValueName,
337                     void* _pValueLocation,
338                     const ::com::sun::star::uno::Type& _rExpectedValueType
339                 ) const;
340 
341         const ::com::sun::star::uno::Any&
342                 impl_get( const ::rtl::OUString& _rValueName ) const;
343 
344         bool    impl_has( const ::rtl::OUString& _rValueName ) const;
345 
346         bool    impl_put( const ::rtl::OUString& _rValueName, const ::com::sun::star::uno::Any& _rValue );
347 
348         bool    impl_remove( const ::rtl::OUString& _rValueName );
349 
350         template< class VALUE_TYPE >
impl_wrap() const351         ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > impl_wrap() const
352         {
353             ::com::sun::star::uno::Sequence< VALUE_TYPE > aValues;
354             *this >>= aValues;
355             ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > aWrappedValues( aValues.getLength() );
356 
357             ::com::sun::star::uno::Any* pO = aWrappedValues.getArray();
358             const VALUE_TYPE* pV = aValues.getConstArray();
359             const sal_Int32 nLen = aValues.getLength();
360             for( sal_Int32 i = 0; i < nLen; ++i )
361                 *(pO++) = ::com::sun::star::uno::makeAny<VALUE_TYPE>( *(pV++) );
362             return aWrappedValues;
363         }
364     };
365 
366 //........................................................................
367 } // namespace comphelper
368 //........................................................................
369 
370 #endif // COMPHELPER_NAMEDVALUECOLLECTION_HXX
371 
372