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