summaryrefslogtreecommitdiffstats
path: root/include/comphelper/namedvaluecollection.hxx
blob: b92646e40a114613a2c9731fa2a98bd30fb1372a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef INCLUDED_COMPHELPER_NAMEDVALUECOLLECTION_HXX
#define INCLUDED_COMPHELPER_NAMEDVALUECOLLECTION_HXX

#include <comphelper/comphelperdllapi.h>

#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/NamedValue.hpp>

#include <vector>
#include <unordered_map>

namespace comphelper
{


    // = NamedValueCollection

    /** a collection of named values, packed in various formats.
    */
    class COMPHELPER_DLLPUBLIC NamedValueCollection
    {
        std::unordered_map< OUString, css::uno::Any >  maValues;
    public:
        NamedValueCollection() = default;

        NamedValueCollection( const NamedValueCollection& _rCopySource ) = default;
        NamedValueCollection(NamedValueCollection&& _rCopySource) noexcept = default;

        NamedValueCollection& operator=( const NamedValueCollection& i_rCopySource ) = default;
        NamedValueCollection& operator=(NamedValueCollection&& i_rCopySource) noexcept = default;

        /** constructs a collection
            @param  _rElements
                the wrapped elements of the collection. The @c Any might contain a sequence of
                property values, a sequence of named values, or directly a property value or named value.
                All other cases are worth an assertion in non-product builds.
        */
        NamedValueCollection( const css::uno::Any& _rElements );

        /** constructs a collection
            @param _rArguments
                a sequence of Any's containing either PropertyValue's or NamedValue's.
        */
        NamedValueCollection( const css::uno::Sequence< css::uno::Any >& _rArguments );

        /** constructs a collection
            @param _rArguments
                a sequence of PropertyValues's
        */
        NamedValueCollection( const css::uno::Sequence< css::beans::PropertyValue >& _rArguments );

        /** constructs a collection
            @param _rArguments
                a sequence of NamedValue's
        */
        NamedValueCollection( const css::uno::Sequence< css::beans::NamedValue >& _rArguments );

        void assign( const css::uno::Sequence< css::uno::Any >& _rArguments )
        {
            impl_assign( _rArguments );
        }

        void clear()
        {
            impl_assign( css::uno::Sequence< css::beans::NamedValue >() );
        }

        /** determines whether or not named values can be extracted from the given value

            @return
                true if and only if the given @c Any contains a @c NamedValue, a
                @c PropertyValue, or a sequence thereof.
        */
        static bool canExtractFrom( css::uno::Any const & i_value );

        /// returns the number of elements in the collection
        size_t  size() const;

        /// determines whether the collection is empty
        bool    empty() const;

        /** returns the names of all elements in the collection
        */
        ::std::vector< OUString >
                getNames() const;

        /** merges the content of another collection into @c this
            @param _rAdditionalValues
                the collection whose values are to be merged
            @param _bOverwriteExisting
                defines whether or not elements which are already present in @c this
                should be overwritten (true) or preserved (false).
            @return @c *this
        */
        NamedValueCollection&
                merge(
                    const NamedValueCollection& _rAdditionalValues,
                    bool _bOverwriteExisting
                );

        /** retrieves a value with a given name from the collection, if it is present

            @param _pAsciiValueName
                the ASCII name of the value to retrieve

            @param _out_rValue
                is the output parameter taking the desired value upon successful return. If
                a value with the given name is not present in the collection, or if a wrong-typed
                value is present, then this parameter will not be touched.

            @retval
                true if there is a value with the given name, which could successfully
                be extracted. In this case, @c _out_rValue will contain the requested
                value.
            @retval
                false, if there is no value with the given name.

            @throws IllegalArgumentException
                in case there is a value with the given name, but it cannot legally assigned to
                _out_rValue.
        */
        template < typename VALUE_TYPE >
        bool get_ensureType( const OUString& _rValueName, VALUE_TYPE& _out_rValue ) const
        {
            return get_ensureType( _rValueName, &_out_rValue, ::cppu::UnoType< VALUE_TYPE >::get() );
        }

        /** retrieves a value with a given name, or defaults it to a given value, if it's not present
            in the collection
        */
        template < typename VALUE_TYPE >
        VALUE_TYPE  getOrDefault( const OUString& _rValueName, const VALUE_TYPE& _rDefault ) const
        {
            VALUE_TYPE retVal( _rDefault );
            get_ensureType( _rValueName, retVal );
            return retVal;
        }

        /** Retrieves a value with a given name, or defaults it to a given value, if it's not present
            in the collection.
            For when you only need a single value from a Sequence<PropertyValue>.
        */
        template < typename VALUE_TYPE >
        static VALUE_TYPE  getOrDefault( const css::uno::Sequence<css::beans::PropertyValue> & rPropSeq,
                    std::u16string_view _rValueName, const VALUE_TYPE& _rDefault )
        {
            VALUE_TYPE retVal( _rDefault );
            get_ensureType( rPropSeq, _rValueName, &retVal, ::cppu::UnoType< VALUE_TYPE >::get() );
            return retVal;
        }

        /** retrieves a (untyped) value with a given name

            If the collection does not contain a value with the given name, an empty
            Any is returned.
        */
        const css::uno::Any& get( const OUString& _rValueName ) const
        {
            return impl_get( _rValueName );
        }

        /** retrieves a (untyped) value with a given name. For when you only need a single value from a Sequence<PropertyValue>.

            If the collection does not contain a value with the given name, an empty
            Any is returned.
        */
        static const css::uno::Any& get( const css::uno::Sequence<css::beans::PropertyValue>& rPropSeq, std::u16string_view _rValueName );

        /// determines whether a value with a given name is present in the collection
        bool has( const OUString& _rValueName ) const
        {
            return impl_has( _rValueName );
        }

        /** puts a value into the collection

            @return true if and only if a value was already present previously, in
                which case it has been overwritten.
        */
        template < typename VALUE_TYPE >
        bool put( const OUString& _rValueName, const VALUE_TYPE& _rValue )
        {
            return impl_put( _rValueName, css::uno::Any( _rValue ) );
        }

        bool put( const OUString& _rValueName, const css::uno::Any& _rValue )
        {
            return impl_put( _rValueName, _rValue );
        }

        /** removes the value with the given name from the collection

            @return true if and only if a value with the given name existed in the collection.
        */
        bool remove( const OUString& _rValueName )
        {
            return impl_remove( _rValueName );
        }

        /** transforms the collection to a sequence of PropertyValues

            @return
                the number of elements in the sequence
        */
        sal_Int32 operator >>= ( css::uno::Sequence< css::beans::PropertyValue >& _out_rValues ) const;

        /** transforms the collection to a sequence of NamedValues

            @return
                the number of elements in the sequence
        */
        sal_Int32 operator >>= ( css::uno::Sequence< css::beans::NamedValue >& _out_rValues ) const;

        /** transforms the collection into a sequence of PropertyValues
        */
        css::uno::Sequence< css::beans::PropertyValue >
                getPropertyValues() const
        {
            css::uno::Sequence< css::beans::PropertyValue > aValues;
            *this >>= aValues;
            return aValues;
        }

        /** returns a Sequence< Any >, containing PropertyValues
        */
        css::uno::Sequence< css::uno::Any >
                getWrappedPropertyValues() const
        {
            return impl_wrap< css::beans::PropertyValue >();
        }

        /** returns a Sequence< Any >, containing NamedValues
        */
        css::uno::Sequence< css::uno::Any >
                getWrappedNamedValues() const
        {
            return impl_wrap< css::beans::NamedValue >();
        }

        /** transforms the collection into a sequence of NamedValues
        */
        css::uno::Sequence< css::beans::NamedValue >
                getNamedValues() const
        {
            css::uno::Sequence< css::beans::NamedValue > aValues;
            *this >>= aValues;
            return aValues;
        }

    private:
        void    impl_assign( const css::uno::Any& i_rWrappedElements );
        void    impl_assign( const css::uno::Sequence< css::uno::Any >& _rArguments );
        void    impl_assign( const css::uno::Sequence< css::beans::PropertyValue >& _rArguments );
        void    impl_assign( const css::uno::Sequence< css::beans::NamedValue >& _rArguments );

        bool    get_ensureType(
                    const OUString& _rValueName,
                    void* _pValueLocation,
                    const css::uno::Type& _rExpectedValueType
                ) const;

        static bool get_ensureType(
                    const css::uno::Sequence<css::beans::PropertyValue> & rPropSeq,
                    std::u16string_view _rValueName,
                    void* _pValueLocation,
                    const css::uno::Type& _rExpectedValueType
                );

        const css::uno::Any&
                impl_get( const OUString& _rValueName ) const;

        bool    impl_has( const OUString& _rValueName ) const;

        bool    impl_put( const OUString& _rValueName, const css::uno::Any& _rValue );

        bool    impl_remove( const OUString& _rValueName );

        template< class VALUE_TYPE >
        css::uno::Sequence< css::uno::Any > impl_wrap() const
        {
            css::uno::Sequence< VALUE_TYPE > aValues;
            *this >>= aValues;
            css::uno::Sequence< css::uno::Any > aWrappedValues( aValues.getLength() );

            css::uno::Any* pO = aWrappedValues.getArray();
            const VALUE_TYPE* pV = aValues.getConstArray();
            const sal_Int32 nLen = aValues.getLength();
            for( sal_Int32 i = 0; i < nLen; ++i )
                *(pO++) = css::uno::Any( *(pV++) );

            return aWrappedValues;
        }
    };


} // namespace comphelper


#endif // INCLUDED_COMPHELPER_NAMEDVALUECOLLECTION_HXX

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */