diff options
Diffstat (limited to '')
-rw-r--r-- | include/oox/helper/containerhelper.hxx | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/include/oox/helper/containerhelper.hxx b/include/oox/helper/containerhelper.hxx new file mode 100644 index 000000000..3b725d509 --- /dev/null +++ b/include/oox/helper/containerhelper.hxx @@ -0,0 +1,298 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * 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 . + */ + +#ifndef INCLUDED_OOX_HELPER_CONTAINERHELPER_HXX +#define INCLUDED_OOX_HELPER_CONTAINERHELPER_HXX + +#include <cstddef> +#include <vector> + +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <oox/dllapi.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +namespace com::sun::star { + namespace container { class XNameAccess; } + namespace container { class XNameContainer; } + namespace uno { class Any; } +} + +namespace oox { + + +/** A range of signed 32-bit integer values. */ +struct ValueRange +{ + sal_Int32 mnFirst; + sal_Int32 mnLast; + + explicit ValueRange( sal_Int32 nValue ) : mnFirst( nValue ), mnLast( nValue ) {} + explicit ValueRange( sal_Int32 nFirst, sal_Int32 nLast ) : mnFirst( nFirst ), mnLast( nLast ) {} + + bool operator==( const ValueRange& rRange ) const { return (mnFirst == rRange.mnFirst) && (mnLast == rRange.mnLast); } + bool operator!=( const ValueRange& rRange ) const { return !(*this == rRange); } + bool contains( const ValueRange& rRange ) const { return (mnFirst <= rRange.mnFirst) && (rRange.mnLast <= mnLast); } + bool intersects( const ValueRange& rRange ) const { return (mnFirst <= rRange.mnLast) && (rRange.mnFirst <= mnLast); } +}; + + +typedef ::std::vector< ValueRange > ValueRangeVector; + + +/** An ordered list of value ranges. The insertion operation will merge + consecutive value ranges. + */ +class OOX_DLLPUBLIC ValueRangeSet +{ +public: + ValueRangeSet() {} + + /** Inserts the passed value range into the range list. */ + void insert( const ValueRange& rRange ); + + /** Returns the ordered list of all value ranges. */ + const ValueRangeVector& getRanges() const { return maRanges; } + +private: + ValueRangeVector maRanges; +}; + + +/** Template for a 2-dimensional array of objects. + + This class template provides a similar interface to the ::std::vector + template. + */ +template< typename Type > +class Matrix +{ +public: + typedef ::std::vector< Type > container_type; + typedef typename container_type::value_type value_type; + typedef typename container_type::pointer pointer; + typedef typename container_type::reference reference; + typedef typename container_type::const_reference const_reference; + typedef typename container_type::size_type size_type; + typedef typename container_type::iterator iterator; + typedef typename container_type::const_iterator const_iterator; + + Matrix() : mnWidth( 0 ) {} + explicit Matrix( size_type nWidth, size_type nHeight ) { resize( nWidth, nHeight ); } + explicit Matrix( size_type nWidth, size_type nHeight, const_reference rData ) { resize( nWidth, nHeight, rData ); } + + bool empty() const { return maData.empty(); } + size_type size() const { return maData.size(); } + size_type width() const { return mnWidth; } + size_type height() const { return empty() ? 0 : (size() / width()); } + + void clear() { resize( 0, 0 ); } + void resize( size_type nWidth, size_type nHeight ) { mnWidth = nWidth; maData.resize( nWidth * nHeight ); } + void resize( size_type nWidth, size_type nHeight, const_reference rData ) { mnWidth = nWidth; maData.resize( nWidth * nHeight, rData ); } + + iterator at( size_type nX, size_type nY ) { return maData.begin() + mnWidth * nY + nX; } + const_iterator at( size_type nX, size_type nY ) const { return maData.begin() + mnWidth * nY + nX; } + + reference operator()( size_type nX, size_type nY ) { return *at( nX, nY ); } + const_reference operator()( size_type nX, size_type nY ) const { return *at( nX, nY ); } + + iterator begin() { return maData.begin(); } + const_iterator begin() const { return maData.begin(); } + iterator end() { return maData.end(); } + const_iterator end() const { return maData.end(); } + + iterator row_begin( size_type nY ) { return at( 0, nY ); } + const_iterator row_begin( size_type nY ) const { return at( 0, nY ); } + iterator row_end( size_type nY ) { return at( mnWidth, nY ); } + const_iterator row_end( size_type nY ) const { return at( mnWidth, nY ); } + + reference row_front( size_type nY ) { return (*this)( 0, nY ); } + const_reference row_front( size_type nY ) const { return (*this)( 0, nY ); } + +private: + container_type maData; + size_type mnWidth; +}; + + +/** Static helper functions for improved API container handling. */ +class OOX_DLLPUBLIC ContainerHelper +{ +public: + + /** Returns a name that is not used in the passed name container. + + @param rxNameAccess com.sun.star.container.XNameAccess interface of + the name container. + + @param rSuggestedName Suggested name for the object. + + @return An unused name. Will be equal to the suggested name, if not + contained, otherwise a numerical index will be appended. + */ + static OUString getUnusedName( + const css::uno::Reference< css::container::XNameAccess >& rxNameAccess, + const OUString& rSuggestedName, + sal_Unicode cSeparator ); + + /** Inserts an object into a name container. + + @param rxNameContainer com.sun.star.container.XNameContainer interface + of the name container. + + @param rName Exact name for the object. + + @param rObject The object to be inserted. + + @return True = object successfully inserted. + */ + static bool insertByName( + const css::uno::Reference< css::container::XNameContainer >& rxNameContainer, + const OUString& rName, + const css::uno::Any& rObject ); + + /** Inserts an object into a name container. + + The function will use an unused name to insert the object, based on the + suggested object name. It is possible to specify whether the existing + object or the new inserted object will be renamed, if the container + already has an object with the name suggested for the new object. + + @param rxNameContainer com.sun.star.container.XNameContainer interface + of the name container. + + @param rSuggestedName Suggested name for the object. + + @param rObject The object to be inserted. + + The new object + will be inserted with a name not yet extant in the container (this + is done by appending a numerical index to the suggested name). + + @return The final name the object is inserted with. Will always be + equal to the suggested name, if parameter bRenameOldExisting is + true. + */ + static OUString insertByUnusedName( + const css::uno::Reference< css::container::XNameContainer >& rxNameContainer, + const OUString& rSuggestedName, + sal_Unicode cSeparator, + const css::uno::Any& rObject ); + + // std::vector and std::map element access -------------------------------- + + /** Returns the pointer to an existing element of the passed vector, or a + null pointer, if the passed index is out of bounds. */ + template< typename VectorType > + static const typename VectorType::value_type* + getVectorElement( const VectorType& rVector, sal_Int32 nIndex ); + + /** Returns the pointer to an existing element of the passed vector, or a + null pointer, if the passed index is out of bounds. */ + template< typename VectorType > + static typename VectorType::value_type* + getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex ); + + /** Returns the reference to an existing element of the passed vector, or + the passed default value, if the passed index is out of bounds. */ + template< typename VectorType > + static const typename VectorType::value_type& + getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault ); + + /** Returns the pointer to an existing element of the passed map, or a null + pointer, if an element with the passed key does not exist. */ + template< typename MapType > + static const typename MapType::mapped_type* + getMapElement( const MapType& rMap, const typename MapType::key_type& rKey ); + + /** Returns the reference to an existing element of the passed map, or the + passed default value, if an element with the passed key does not exist. */ + template< typename MapType > + static const typename MapType::mapped_type& + getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault ); + + /** Creates a UNO sequence of sequences from a matrix with copies of all elements. + + @param rMatrix The matrix to be converted to a sequence of sequences. + + @return A com.sun.star.uno.Sequence object containing + com.sun.star.uno.Sequence objects with copies of all objects + contained in the passed matrix. + */ + template< typename MatrixType > + static css::uno::Sequence< css::uno::Sequence< typename MatrixType::value_type > > + matrixToSequenceSequence( const MatrixType& rMatrix ); +}; + + +template< typename VectorType > +/*static*/ const typename VectorType::value_type* ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex ) +{ + return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : nullptr; +} + +template< typename VectorType > +/*static*/ typename VectorType::value_type* ContainerHelper::getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex ) +{ + return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : nullptr; +} + +template< typename VectorType > +/*static*/ const typename VectorType::value_type& ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault ) +{ + return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? rVector[ static_cast< size_t >( nIndex ) ] : rDefault; +} + +template< typename MapType > +/*static*/ const typename MapType::mapped_type* ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey ) +{ + typename MapType::const_iterator aIt = rMap.find( rKey ); + return (aIt == rMap.end()) ? nullptr : &aIt->second; +} + +template< typename MapType > +/*static*/ const typename MapType::mapped_type& ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault ) +{ + typename MapType::const_iterator aIt = rMap.find( rKey ); + return (aIt == rMap.end()) ? rDefault : aIt->second; +} + +template< typename MatrixType > +/*static*/ css::uno::Sequence< css::uno::Sequence< typename MatrixType::value_type > > ContainerHelper::matrixToSequenceSequence( const MatrixType& rMatrix ) +{ + typedef typename MatrixType::value_type ValueType; + css::uno::Sequence< css::uno::Sequence< ValueType > > aSeq; + if( !rMatrix.empty() ) + { + aSeq.realloc( static_cast< sal_Int32 >( rMatrix.height() ) ); + auto pSeq = aSeq.getArray(); + for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow ) + pSeq[ static_cast< sal_Int32 >( nRow ) ] = + css::uno::Sequence< ValueType >( &rMatrix.row_front( nRow ), static_cast< sal_Int32 >( rMatrix.width() ) ); + } + return aSeq; +} + + +} // namespace oox + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |