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