blob: 5cda95bc822d43ed5d436428284235e3b91232ae [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#ifndef _COMPHELPER_SEQUENCE_HXX_
#define _COMPHELPER_SEQUENCE_HXX_
#ifndef INCLUDED_ALGORITHM
#include <algorithm> // copy algorithm
#define INCLUDED_ALGORITHM
#endif
#include <com/sun/star/uno/Sequence.hxx>
#include <osl/diagnose.h>
#include "comphelper/comphelperdllapi.h"
#include <vector>
//.........................................................................
namespace comphelper
{
//.........................................................................
namespace staruno = ::com::sun::star::uno;
//-------------------------------------------------------------------------
/** search the given string within the given sequence, return the positions where it was found.
if _bOnlyFirst is sal_True, only the first occurence will be returned.
*/
COMPHELPER_DLLPUBLIC staruno::Sequence<sal_Int16> findValue(const staruno::Sequence< ::rtl::OUString >& _rList, const ::rtl::OUString& _rValue, sal_Bool _bOnlyFirst = sal_False);
/** Checks if the name exists
*
* \param Value The value to search for.
* \param _aList The list in which to search for the value.
* \return <TRUE/> if the value can be found, otherwise <FALSE/>.
*/
COMPHELPER_DLLPUBLIC sal_Bool existsValue(const ::rtl::OUString& Value,const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _aList);
//-------------------------------------------------------------------------
namespace internal
{
template <class T>
void implCopySequence(const T* _pSource, T*& _pDest, sal_Int32 _nSourceLen)
{
for (sal_Int32 i=0; i<_nSourceLen; ++i, ++_pSource, ++_pDest)
*_pDest = *_pSource;
}
}
//-------------------------------------------------------------------------
/// concat two sequences
template <class T>
staruno::Sequence<T> concatSequences(const staruno::Sequence<T>& _rLeft, const staruno::Sequence<T>& _rRight)
{
sal_Int32 nLeft(_rLeft.getLength()), nRight(_rRight.getLength());
const T* pLeft = _rLeft.getConstArray();
const T* pRight = _rRight.getConstArray();
sal_Int32 nReturnLen(nLeft + nRight);
staruno::Sequence<T> aReturn(nReturnLen);
T* pReturn = aReturn.getArray();
internal::implCopySequence(pLeft, pReturn, nLeft);
internal::implCopySequence(pRight, pReturn, nRight);
return aReturn;
}
//-------------------------------------------------------------------------
/// concat three sequences
template <class T>
staruno::Sequence<T> concatSequences(const staruno::Sequence<T>& _rLeft, const staruno::Sequence<T>& _rMiddle, const staruno::Sequence<T>& _rRight)
{
sal_Int32 nLeft(_rLeft.getLength()), nMiddle(_rMiddle.getLength()), nRight(_rRight.getLength());
const T* pLeft = _rLeft.getConstArray();
const T* pMiddle = _rMiddle.getConstArray();
const T* pRight = _rRight.getConstArray();
sal_Int32 nReturnLen(nLeft + nMiddle + nRight);
staruno::Sequence<T> aReturn(nReturnLen);
T* pReturn = aReturn.getArray();
internal::implCopySequence(pLeft, pReturn, nLeft);
internal::implCopySequence(pMiddle, pReturn, nMiddle);
internal::implCopySequence(pRight, pReturn, nRight);
return aReturn;
}
//-------------------------------------------------------------------------
/// remove a specified element from a sequences
template<class T>
void removeElementAt(staruno::Sequence<T>& _rSeq, sal_Int32 _nPos)
{
sal_uInt32 nLength = _rSeq.getLength();
OSL_ENSURE(0 <= _nPos && (sal_uInt32)_nPos < nLength, "invalid index");
for (sal_uInt32 i = (sal_uInt32)_nPos + 1; i < nLength; ++i)
{
_rSeq[i-1] = _rSeq[i];
}
_rSeq.realloc(nLength-1);
}
//=====================================================================
//= iterating through sequences
//=====================================================================
class SAL_NO_VTABLE IIterator
{
public:
virtual sal_Bool hasMoreElements() const = 0;
virtual ::com::sun::star::uno::Any nextElement() = 0;
};
/** a helper class for iterating through a sequence
*/
template <class TYPE>
class OSequenceIterator : public IIterator
{
const TYPE* m_pElements;
sal_Int32 m_nLen;
const TYPE* m_pCurrent;
public:
/** contrcuct a sequence iterator from a sequence
*/
OSequenceIterator(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq);
/** contrcuct a sequence iterator from a Any containing a sequence
*/
OSequenceIterator(const ::com::sun::star::uno::Any& _rSequenceAny);
virtual sal_Bool hasMoreElements() const;
virtual ::com::sun::star::uno::Any nextElement();
protected:
void construct(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq);
};
//---------------------------------------------------------------------
template <class TYPE>
OSequenceIterator<TYPE>::OSequenceIterator(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq)
:m_pElements(NULL)
,m_nLen(0)
,m_pCurrent(NULL)
{
construct(_rSeq);
}
//---------------------------------------------------------------------
template <class TYPE>
OSequenceIterator<TYPE>::OSequenceIterator(const ::com::sun::star::uno::Any& _rSequenceAny)
:m_pElements(NULL)
,m_nLen(0)
,m_pCurrent(NULL)
{
::com::sun::star::uno::Sequence< TYPE > aContainer;
#ifdef DBG_UTIL
sal_Bool bSuccess =
#endif
_rSequenceAny >>= aContainer;
#ifdef DBG_UTIL
OSL_ENSURE(bSuccess, "OSequenceIterator::OSequenceIterator: invalid Any!");
#endif
construct(aContainer);
}
//---------------------------------------------------------------------
template <class TYPE>
void OSequenceIterator<TYPE>::construct(const ::com::sun::star::uno::Sequence< TYPE >& _rSeq)
{
m_pElements = _rSeq.getConstArray();
m_nLen = _rSeq.getLength();
m_pCurrent = m_pElements;
}
//---------------------------------------------------------------------
template <class TYPE>
sal_Bool OSequenceIterator<TYPE>::hasMoreElements() const
{
return m_pCurrent - m_pElements < m_nLen;
}
//---------------------------------------------------------------------
template <class TYPE>
::com::sun::star::uno::Any OSequenceIterator<TYPE>::nextElement()
{
return ::com::sun::star::uno::makeAny(*m_pCurrent++);
}
//-------------------------------------------------------------------------
/** Copy from a plain C/C++ array into a Sequence.
@tpl SrcType
Array element type. Must be assignable to DstType
@tpl DstType
Sequence element type. Must be assignable from SrcType
@param i_pArray
Valid pointer to at least num elements of type SrcType
@param nNum
Number of array elements to copy
@return the resulting Sequence
@attention when copying from e.g. a double array to a
Sequence<int>, no proper rounding will be performed, but the
values will be truncated. There's currently no measure to
prevent or detect precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
::com::sun::star::uno::Sequence< DstType > arrayToSequence( const SrcType* i_pArray, sal_Int32 nNum )
{
::com::sun::star::uno::Sequence< DstType > result( nNum );
::std::copy( i_pArray, i_pArray+nNum, result.getArray() );
return result;
}
//-------------------------------------------------------------------------
/** Copy from a Sequence into a plain C/C++ array
@tpl SrcType
Sequence element type. Must be assignable to DstType
@tpl DstType
Array element type. Must be assignable from SrcType
@param io_pArray
Valid pointer to at least i_Sequence.getLength() elements of
type DstType
@param i_Sequence
Reference to a Sequence of SrcType elements
@return a pointer to the array
@attention when copying from e.g. a Sequence<double> to an int
array, no proper rounding will be performed, but the values
will be truncated. There's currently no measure to prevent or
detect precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
DstType* sequenceToArray( DstType* io_pArray, const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
{
::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), io_pArray );
return io_pArray;
}
//-------------------------------------------------------------------------
/** Copy from a container into a Sequence
@tpl SrcType
Container type. This type must fulfill the STL container
concept, in particular, the size(), begin() and end() methods
must be available and have the usual semantics.
@tpl DstType
Sequence element type. Must be assignable from SrcType's
elements
@param i_Container
Reference to the input contain with elements of type SrcType
@return the generated Sequence
@attention this function always performs a copy. Furthermore,
when copying from e.g. a vector<double> to a Sequence<int>, no
proper rounding will be performed, but the values will be
truncated. There's currently no measure to prevent or detect
precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
::com::sun::star::uno::Sequence< DstType > containerToSequence( const SrcType& i_Container )
{
::com::sun::star::uno::Sequence< DstType > result( i_Container.size() );
::std::copy( i_Container.begin(), i_Container.end(), result.getArray() );
return result;
}
template <typename T>
inline ::com::sun::star::uno::Sequence<T> containerToSequence(
::std::vector<T> const& v )
{
return ::com::sun::star::uno::Sequence<T>(
v.empty() ? 0 : &v[0], static_cast<sal_Int32>(v.size()) );
}
//-------------------------------------------------------------------------
/** Copy from a Sequence into a container
@tpl SrcType
Sequence element type. Must be assignable to SrcType's
elements
@tpl DstType
Container type. This type must fulfill the STL container and
sequence concepts, in particular, the begin(), end() and the
unary constructor DstType(int) methods must be available and
have the usual semantics.
@param i_Sequence
Reference to a Sequence of SrcType elements
@return the generated container
@attention this function always performs a copy. Furthermore,
when copying from e.g. a Sequence<double> to a vector<int>, no
proper rounding will be performed, but the values will be
truncated. There's currently no measure to prevent or detect
precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
DstType sequenceToContainer( const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
{
DstType result( i_Sequence.getLength() );
::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), result.begin() );
return result;
}
//-------------------------------------------------------------------------
/** Copy from a Sequence into an existing container
This potentially saves a needless extra copy operation over
the whole container, as it passes the target object by
reference.
@tpl SrcType
Sequence element type. Must be assignable to SrcType's
elements
@tpl DstType
Container type. This type must fulfill the STL container and
sequence concepts, in particular, the begin(), end() and
resize(int) methods must be available and have the usual
semantics.
@param o_Output
Reference to the target container
@param i_Sequence
Reference to a Sequence of SrcType elements
@return a non-const reference to the given container
@attention this function always performs a copy. Furthermore,
when copying from e.g. a Sequence<double> to a vector<int>, no
proper rounding will be performed, but the values will be
truncated. There's currently no measure to prevent or detect
precision loss, overflow or truncation.
*/
template < typename DstType, typename SrcType >
DstType& sequenceToContainer( DstType& o_Output, const ::com::sun::star::uno::Sequence< SrcType >& i_Sequence )
{
o_Output.resize( i_Sequence.getLength() );
::std::copy( i_Sequence.getConstArray(), i_Sequence.getConstArray()+i_Sequence.getLength(), o_Output.begin() );
return o_Output;
}
//.........................................................................
} // namespace comphelper
//.........................................................................
#endif // _COMPHELPER_SEQUENCE_HXX_