Line data Source code
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 :
20 : #ifndef INCLUDED_COMPHELPER_SEQUENCE_HXX
21 : #define INCLUDED_COMPHELPER_SEQUENCE_HXX
22 :
23 : #include <algorithm>
24 : #include <com/sun/star/uno/Sequence.hxx>
25 : #include <osl/diagnose.h>
26 : #include <comphelper/comphelperdllapi.h>
27 :
28 : #include <vector>
29 :
30 : namespace comphelper
31 : {
32 : /** search the given string within the given sequence, return the positions where it was found.
33 : if _bOnlyFirst is sal_True, only the first occurrence will be returned.
34 : */
35 : COMPHELPER_DLLPUBLIC css::uno::Sequence<sal_Int16> findValue(const css::uno::Sequence< OUString >& _rList, const OUString& _rValue, bool _bOnlyFirst = false);
36 :
37 : namespace internal
38 : {
39 : template <class T>
40 11616 : void implCopySequence(const T* _pSource, T*& _pDest, sal_Int32 _nSourceLen)
41 : {
42 125510 : for (sal_Int32 i=0; i<_nSourceLen; ++i, ++_pSource, ++_pDest)
43 113894 : *_pDest = *_pSource;
44 11616 : }
45 : }
46 :
47 : /// concat two sequences
48 : template <class T>
49 4740 : css::uno::Sequence<T> concatSequences(const css::uno::Sequence<T>& _rLeft, const css::uno::Sequence<T>& _rRight)
50 : {
51 4740 : sal_Int32 nLeft(_rLeft.getLength()), nRight(_rRight.getLength());
52 4740 : const T* pLeft = _rLeft.getConstArray();
53 4740 : const T* pRight = _rRight.getConstArray();
54 :
55 4740 : sal_Int32 nReturnLen(nLeft + nRight);
56 4740 : css::uno::Sequence<T> aReturn(nReturnLen);
57 4740 : T* pReturn = aReturn.getArray();
58 :
59 4740 : internal::implCopySequence(pLeft, pReturn, nLeft);
60 4740 : internal::implCopySequence(pRight, pReturn, nRight);
61 :
62 4740 : return aReturn;
63 : }
64 :
65 :
66 : /// concat three sequences
67 : template <class T>
68 712 : css::uno::Sequence<T> concatSequences(const css::uno::Sequence<T>& _rLeft, const css::uno::Sequence<T>& _rMiddle, const css::uno::Sequence<T>& _rRight)
69 : {
70 712 : sal_Int32 nLeft(_rLeft.getLength()), nMiddle(_rMiddle.getLength()), nRight(_rRight.getLength());
71 712 : const T* pLeft = _rLeft.getConstArray();
72 712 : const T* pMiddle = _rMiddle.getConstArray();
73 712 : const T* pRight = _rRight.getConstArray();
74 :
75 712 : sal_Int32 nReturnLen(nLeft + nMiddle + nRight);
76 712 : css::uno::Sequence<T> aReturn(nReturnLen);
77 712 : T* pReturn = aReturn.getArray();
78 :
79 712 : internal::implCopySequence(pLeft, pReturn, nLeft);
80 712 : internal::implCopySequence(pMiddle, pReturn, nMiddle);
81 712 : internal::implCopySequence(pRight, pReturn, nRight);
82 :
83 712 : return aReturn;
84 : }
85 :
86 :
87 : /// remove a specified element from a sequences
88 : template<class T>
89 8384 : void removeElementAt(css::uno::Sequence<T>& _rSeq, sal_Int32 _nPos)
90 : {
91 8384 : sal_Int32 nLength = _rSeq.getLength();
92 :
93 : OSL_ENSURE(0 <= _nPos && _nPos < nLength, "invalid index");
94 :
95 85952 : for (sal_Int32 i = _nPos + 1; i < nLength; ++i)
96 : {
97 77568 : _rSeq[i-1] = _rSeq[i];
98 : }
99 :
100 8384 : _rSeq.realloc(nLength-1);
101 8384 : }
102 :
103 :
104 : //= iterating through sequences
105 :
106 : /** a helper class for iterating through a sequence
107 : */
108 : template <class TYPE>
109 : class OSequenceIterator
110 : {
111 : const TYPE* m_pElements;
112 : sal_Int32 m_nLen;
113 : const TYPE* m_pCurrent;
114 :
115 : public:
116 : /** contrcuct a sequence iterator from a sequence
117 : */
118 : OSequenceIterator(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq);
119 : /** contrcuct a sequence iterator from a Any containing a sequence
120 : */
121 : OSequenceIterator(const ::com::sun::star::uno::Any& _rSequenceAny);
122 :
123 : bool hasMoreElements() const;
124 : ::com::sun::star::uno::Any nextElement();
125 :
126 : private:
127 : void construct(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq);
128 : };
129 :
130 :
131 : template <class TYPE>
132 152118 : OSequenceIterator<TYPE>::OSequenceIterator(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq)
133 : :m_pElements(NULL)
134 : ,m_nLen(0)
135 152118 : ,m_pCurrent(NULL)
136 : {
137 152118 : construct(_rSeq);
138 152118 : }
139 :
140 :
141 : template <class TYPE>
142 0 : OSequenceIterator<TYPE>::OSequenceIterator(const ::com::sun::star::uno::Any& _rSequenceAny)
143 : :m_pElements(NULL)
144 : ,m_nLen(0)
145 0 : ,m_pCurrent(NULL)
146 : {
147 0 : ::com::sun::star::uno::Sequence< TYPE > aContainer;
148 0 : bool bSuccess = _rSequenceAny >>= aContainer;
149 : OSL_ENSURE(bSuccess, "OSequenceIterator::OSequenceIterator: invalid Any!");
150 : (void)bSuccess;
151 0 : construct(aContainer);
152 0 : }
153 :
154 :
155 : template <class TYPE>
156 152118 : void OSequenceIterator<TYPE>::construct(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq)
157 : {
158 152118 : m_pElements = _rSeq.getConstArray();
159 152118 : m_nLen = _rSeq.getLength();
160 152118 : m_pCurrent = m_pElements;
161 152118 : }
162 :
163 :
164 : template <class TYPE>
165 664978 : bool OSequenceIterator<TYPE>::hasMoreElements() const
166 : {
167 664978 : return m_pCurrent - m_pElements < m_nLen;
168 : }
169 :
170 :
171 : template <class TYPE>
172 512860 : ::com::sun::star::uno::Any OSequenceIterator<TYPE>::nextElement()
173 : {
174 512860 : return ::com::sun::star::uno::makeAny(*m_pCurrent++);
175 : }
176 :
177 :
178 : /** Copy from a plain C/C++ array into a Sequence.
179 :
180 : @tpl SrcType
181 : Array element type. Must be assignable to DstType
182 :
183 : @tpl DstType
184 : Sequence element type. Must be assignable from SrcType
185 :
186 : @param i_pArray
187 : Valid pointer to at least num elements of type SrcType
188 :
189 : @param nNum
190 : Number of array elements to copy
191 :
192 : @return the resulting Sequence
193 :
194 : @attention when copying from e.g. a double array to a
195 : Sequence<int>, no proper rounding will be performed, but the
196 : values will be truncated. There's currently no measure to
197 : prevent or detect precision loss, overflow or truncation.
198 : */
199 : template < typename DstType, typename SrcType >
200 0 : ::com::sun::star::uno::Sequence< DstType > arrayToSequence( const SrcType* i_pArray, sal_Int32 nNum )
201 : {
202 0 : ::com::sun::star::uno::Sequence< DstType > result( nNum );
203 0 : ::std::copy( i_pArray, i_pArray+nNum, result.getArray() );
204 0 : return result;
205 : }
206 :
207 :
208 : /** Copy from a Sequence into a plain C/C++ array
209 :
210 : @tpl SrcType
211 : Sequence element type. Must be assignable to DstType
212 :
213 : @tpl DstType
214 : Array element type. Must be assignable from SrcType
215 :
216 : @param io_pArray
217 : Valid pointer to at least i_Sequence.getLength() elements of
218 : type DstType
219 :
220 : @param i_Sequence
221 : Reference to a Sequence of SrcType elements
222 :
223 : @return a pointer to the array
224 :
225 : @attention when copying from e.g. a Sequence<double> to an int
226 : array, no proper rounding will be performed, but the values
227 : will be truncated. There's currently no measure to prevent or
228 : detect precision loss, overflow or truncation.
229 : */
230 : template < typename DstType, typename SrcType >
231 0 : DstType* sequenceToArray( DstType* io_pArray, const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
232 : {
233 0 : ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), io_pArray );
234 0 : return io_pArray;
235 : }
236 :
237 :
238 : /** Copy from a container into a Sequence
239 :
240 : @tpl SrcType
241 : Container type. This type must fulfill the STL container
242 : concept, in particular, the size(), begin() and end() methods
243 : must be available and have the usual semantics.
244 :
245 : @tpl DstType
246 : Sequence element type. Must be assignable from SrcType's
247 : elements
248 :
249 : @param i_Container
250 : Reference to the input contain with elements of type SrcType
251 :
252 : @return the generated Sequence
253 :
254 : @attention this function always performs a copy. Furthermore,
255 : when copying from e.g. a vector<double> to a Sequence<int>, no
256 : proper rounding will be performed, but the values will be
257 : truncated. There's currently no measure to prevent or detect
258 : precision loss, overflow or truncation.
259 : */
260 : template < typename DstType, typename SrcType >
261 8 : ::com::sun::star::uno::Sequence< DstType > containerToSequence( const SrcType& i_Container )
262 : {
263 8 : ::com::sun::star::uno::Sequence< DstType > result( i_Container.size() );
264 8 : ::std::copy( i_Container.begin(), i_Container.end(), result.getArray() );
265 8 : return result;
266 : }
267 :
268 : template <typename T>
269 142076 : inline ::com::sun::star::uno::Sequence<T> containerToSequence(
270 : ::std::vector<T> const& v )
271 : {
272 : return ::com::sun::star::uno::Sequence<T>(
273 142076 : v.empty() ? 0 : &v[0], static_cast<sal_Int32>(v.size()) );
274 : }
275 :
276 :
277 : /** Copy from a Sequence into a container
278 :
279 : @tpl SrcType
280 : Sequence element type. Must be assignable to SrcType's
281 : elements
282 :
283 : @tpl DstType
284 : Container type. This type must fulfill the STL container and
285 : sequence concepts, in particular, the begin(), end() and the
286 : unary constructor DstType(int) methods must be available and
287 : have the usual semantics.
288 :
289 : @param i_Sequence
290 : Reference to a Sequence of SrcType elements
291 :
292 : @return the generated container
293 :
294 : @attention this function always performs a copy. Furthermore,
295 : when copying from e.g. a Sequence<double> to a vector<int>, no
296 : proper rounding will be performed, but the values will be
297 : truncated. There's currently no measure to prevent or detect
298 : precision loss, overflow or truncation.
299 : */
300 : template < typename DstType, typename SrcType >
301 0 : DstType sequenceToContainer( const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
302 : {
303 0 : DstType result( i_Sequence.getLength() );
304 0 : ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), result.begin() );
305 0 : return result;
306 : }
307 :
308 : /** Copy from a Sequence into an existing container
309 :
310 : This potentially saves a needless extra copy operation over
311 : the whole container, as it passes the target object by
312 : reference.
313 :
314 : @tpl SrcType
315 : Sequence element type. Must be assignable to SrcType's
316 : elements
317 :
318 : @tpl DstType
319 : Container type. This type must fulfill the STL container and
320 : sequence concepts, in particular, the begin(), end() and
321 : resize(int) methods must be available and have the usual
322 : semantics.
323 :
324 : @param o_Output
325 : Reference to the target container
326 :
327 : @param i_Sequence
328 : Reference to a Sequence of SrcType elements
329 :
330 : @return a non-const reference to the given container
331 :
332 : @attention this function always performs a copy. Furthermore,
333 : when copying from e.g. a Sequence<double> to a vector<int>, no
334 : proper rounding will be performed, but the values will be
335 : truncated. There's currently no measure to prevent or detect
336 : precision loss, overflow or truncation.
337 : */
338 : template < typename DstType, typename SrcType >
339 10 : DstType& sequenceToContainer( DstType& o_Output, const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
340 : {
341 10 : o_Output.resize( i_Sequence.getLength() );
342 10 : ::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), o_Output.begin() );
343 10 : return o_Output;
344 : }
345 :
346 :
347 : } // namespace comphelper
348 :
349 :
350 :
351 : #endif // INCLUDED_COMPHELPER_SEQUENCE_HXX
352 :
353 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|