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_SEQUENCEASVECTOR_HXX_
25 #define _COMPHELPER_SEQUENCEASVECTOR_HXX_
26 
27 //_______________________________________________
28 // includes
29 
30 #include <vector>
31 #include <algorithm>
32 #include <com/sun/star/uno/Sequence.hxx>
33 
34 #ifndef _COM_SUN_STAR_BEANS_IllegalTypeException_HPP_
35 #include <com/sun/star/beans/IllegalTypeException.hpp>
36 #endif
37 
38 //_______________________________________________
39 // namespace
40 
41 namespace comphelper{
42 
43 //_______________________________________________
44 // definitions
45 
46 /** @short  Implements a stl vector on top of any
47             uno sequence.
48 
49     @descr  That provides the possibility to modify
50             sequences very easy ...
51             Of course this can be useful only, if
52             count of modifications is high, so copying
53             of the sequence make sense!
54  */
55 template< class TElementType >
56 class SequenceAsVector : public ::std::vector< TElementType >
57 {
58     //-------------------------------------------
59     // types
60 
61     public:
62 
63         //---------------------------------------
64         /** @short  When inheriting from a template using typename is generally required when using
65                     types from the base! */
66         typedef typename ::std::vector< TElementType >::const_iterator const_iterator;
67 
68     //-------------------------------------------
69     // interface
70     public:
71 
72         //---------------------------------------
73         /** @short  default ctor, to create an empty list.
74          */
SequenceAsVector()75         SequenceAsVector()
76         {}
77 
78         //---------------------------------------
79         /** @short  default dtor
80          */
~SequenceAsVector()81         ~SequenceAsVector()
82         {}
83 
84         //---------------------------------------
85         /** @short  creates a new vector with the given length.
86 
87             @param  nLength
88                     the number of elements for the new vector.
89          */
SequenceAsVector(sal_Int32 nLength)90         explicit SequenceAsVector(sal_Int32 nLength) :
91             ::std::vector< TElementType >( static_cast< size_t >( nLength ) )
92         {
93         }
94 
95         //---------------------------------------
96         /** @short  creates a new deque from the given uno sequence.
97 
98             @param  lSource
99                     contains the new items for this deque.
100          */
SequenceAsVector(const::com::sun::star::uno::Sequence<TElementType> & lSource)101         SequenceAsVector(const ::com::sun::star::uno::Sequence< TElementType >& lSource)
102         {
103             (*this) << lSource;
104         }
105 
106         //---------------------------------------
107         /** @short      creates a new instance from the given Any, which
108                         of course must contain a valid sequence using the
109                         right element type for every item.
110 
111             @attention  If the given Any is an empty one
112                         (if its set to VOID), no exception
113                         is thrown. In such case this instance will
114                         be created as an empty one too!
115 
116             @param      aSource
117                         this any must contain a suitable sequence. :-)
118 
119             @throw      A <type scope="com::sun::star::beans">IllegalTypeException</type>
120                         if an unsupported element inside this Any
121                         is given. An empty Any reset this instance!
122          */
SequenceAsVector(const::com::sun::star::uno::Any & aSource)123         SequenceAsVector(const ::com::sun::star::uno::Any& aSource)
124         {
125             (*this) << aSource;
126         }
127 
128         //---------------------------------------
129         /** @short  fill this instance from the given uno sequence.
130 
131             @param  lSource
132                     contains the new items for this deque.
133          */
operator <<(const::com::sun::star::uno::Sequence<TElementType> & lSource)134         void operator<<(const ::com::sun::star::uno::Sequence< TElementType >& lSource)
135         {
136             this->clear();
137 
138                   sal_Int32     c       = lSource.getLength();
139             const TElementType* pSource = lSource.getConstArray();
140 
141             for (sal_Int32 i=0; i<c; ++i)
142                 this->push_back(pSource[i]);
143         }
144 
145         //---------------------------------------
146         /** @short      fill this instance from the given Any, which
147                         of course must contain a valid sequence using the
148                         right element type for every item.
149 
150             @attention  If the given Any is an empty one
151                         (if its set to VOID), no exception
152                         is thrown. In such case this instance will
153                         be created as an empty one too!
154 
155             @param      aSource
156                         this any must contain a suitable sequence. :-)
157 
158             @throw      A <type scope="com::sun::star::beans">IllegalTypeException</type>
159                         if an unsupported element inside this Any
160                         is given. An empty Any reset this instance!
161          */
operator <<(const::com::sun::star::uno::Any & aSource)162         void operator<<(const ::com::sun::star::uno::Any& aSource)
163         {
164             // An empty Any reset this instance!
165             if (!aSource.hasValue())
166             {
167                 this->clear();
168                 return;
169             }
170 
171             ::com::sun::star::uno::Sequence< TElementType > lSource;
172             if (!(aSource >>= lSource))
173                 throw ::com::sun::star::beans::IllegalTypeException(
174                         ::rtl::OUString::createFromAscii("SequenceAsVector operator<<(Any) was called with an unsupported Any type."),
175                         ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >());
176 
177             (*this) << lSource;
178         }
179 
180         //---------------------------------------
181         /** @short  converts this instance to an uno sequence.
182 
183             @param  lDestination
184                     target sequence for converting.
185          */
operator >>(::com::sun::star::uno::Sequence<TElementType> & lDestination) const186         void operator>>(::com::sun::star::uno::Sequence< TElementType >& lDestination) const
187         {
188             sal_Int32 c = (sal_Int32)this->size();
189             lDestination.realloc(c);
190             TElementType* pDestination = lDestination.getArray();
191 
192             sal_Int32 i = 0;
193             for (typename std::vector<TElementType>::const_iterator pThis  = this->begin();
194                                                                     pThis != this->end()  ;
195                                                                     ++pThis           )
196             {
197                 pDestination[i] = *pThis;
198                 ++i;
199             }
200         }
201 
202         //---------------------------------------
203         /** @short  converts this instance to an uno any
204                     which contains a suitable sequence
205                     of items of this stl struct.
206 
207             @param  aDestination
208                     target any for converting.
209          */
operator >>(::com::sun::star::uno::Any & aDestination) const210         void operator>>(::com::sun::star::uno::Any& aDestination) const
211         {
212             sal_Int32                                       c            = (sal_Int32)this->size();
213             ::com::sun::star::uno::Sequence< TElementType > lDestination(c);
214             TElementType*                                   pDestination = lDestination.getArray();
215 
216             sal_Int32 i = 0;
217             for (typename std::vector<TElementType>::const_iterator pThis  = this->begin();
218                                                                     pThis != this->end()  ;
219                                                                     ++pThis           )
220             {
221                 pDestination[i] = *pThis;
222                 ++i;
223             }
224 
225             aDestination <<= lDestination;
226         }
227 
228         //---------------------------------------
229         /** @short      converts this deque to a suitable uno
230                         sequence which contains all items.
231 
232             @attention  It return a const sequence to prevent
233                         the outside code against using of this
234                         return value as [in/]out parameter for
235                         direct function calls!
236                         Of course it can be casted to non const
237                         ... but then its a problem of the outside
238                         code :-)
239 
240             @return     A (const!) sequence, which contains all items of
241                         this deque.
242          */
getAsConstList() const243         const ::com::sun::star::uno::Sequence< TElementType > getAsConstList() const
244         {
245             ::com::sun::star::uno::Sequence< TElementType > lDestination;
246             (*this) >> lDestination;
247             return lDestination;
248         }
249 };
250 
251 } // namespace comphelper
252 
253 #endif // _COMPHELPER_SEQUENCEASVECTOR_HXX_
254 
255