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 occurence 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