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 OOX_HELPER_CONTAINERHELPER_HXX
21 : #define OOX_HELPER_CONTAINERHELPER_HXX
22 :
23 : #include <map>
24 : #include <vector>
25 : #include <com/sun/star/uno/Reference.h>
26 : #include <com/sun/star/uno/Sequence.h>
27 : #include "oox/dllapi.h"
28 :
29 : namespace rtl { class OUString; }
30 :
31 : namespace com { namespace sun { namespace star {
32 : namespace container { class XIndexAccess; }
33 : namespace container { class XIndexContainer; }
34 : namespace container { class XNameAccess; }
35 : namespace container { class XNameContainer; }
36 : namespace uno { class XComponentContext; }
37 : } } }
38 :
39 : namespace oox {
40 :
41 : // ============================================================================
42 :
43 : /** A range of signed 32-bit integer values. */
44 : struct ValueRange
45 : {
46 : sal_Int32 mnFirst;
47 : sal_Int32 mnLast;
48 :
49 114 : inline explicit ValueRange( sal_Int32 nValue = 0 ) : mnFirst( nValue ), mnLast( nValue ) {}
50 201 : inline explicit ValueRange( sal_Int32 nFirst, sal_Int32 nLast ) : mnFirst( nFirst ), mnLast( nLast ) {}
51 :
52 : inline bool operator==( const ValueRange& rRange ) const { return (mnFirst == rRange.mnFirst) && (mnLast == rRange.mnLast); }
53 : inline bool operator!=( const ValueRange& rRange ) const { return !(*this == rRange); }
54 : inline bool contains( sal_Int32 nValue ) const { return (mnFirst <= nValue) && (nValue <= mnLast); }
55 0 : inline bool contains( const ValueRange& rRange ) const { return (mnFirst <= rRange.mnFirst) && (rRange.mnLast <= mnLast); }
56 0 : inline bool intersects( const ValueRange& rRange ) const { return (mnFirst <= rRange.mnLast) && (rRange.mnFirst <= mnLast); }
57 : };
58 :
59 : // ----------------------------------------------------------------------------
60 :
61 : typedef ::std::vector< ValueRange > ValueRangeVector;
62 :
63 : // ----------------------------------------------------------------------------
64 :
65 : /** An ordered list of value ranges. The insertion operation will merge
66 : consecutive value ranges.
67 : */
68 554 : class OOX_DLLPUBLIC ValueRangeSet
69 : {
70 : public:
71 225 : inline explicit ValueRangeSet() {}
72 :
73 : /** Inserts the passed value into the range list. */
74 : inline void insert( sal_Int32 nValue ) { insert( ValueRange( nValue ) ); }
75 : /** Inserts the passed value range into the range list. */
76 : void insert( const ValueRange& rRange );
77 :
78 : /** Returns the ordered list of all value ranges. */
79 153 : inline const ValueRangeVector& getRanges() const { return maRanges; }
80 :
81 : private:
82 : ValueRangeVector maRanges;
83 : };
84 :
85 : // ============================================================================
86 :
87 : /** Template for a 2-dimensional array of objects.
88 :
89 : This class template provides a similar interface to the ::std::vector
90 : template.
91 : */
92 : template< typename Type >
93 0 : class Matrix
94 : {
95 : public:
96 : typedef ::std::vector< Type > container_type;
97 : typedef typename container_type::value_type value_type;
98 : typedef typename container_type::pointer pointer;
99 : typedef typename container_type::reference reference;
100 : typedef typename container_type::const_reference const_reference;
101 : typedef typename container_type::size_type size_type;
102 : typedef typename container_type::iterator iterator;
103 : typedef typename container_type::const_iterator const_iterator;
104 :
105 0 : inline explicit Matrix() : mnWidth( 0 ) {}
106 0 : inline explicit Matrix( size_type nWidth, size_type nHeight ) { this->resize( nWidth, nHeight ); }
107 0 : inline explicit Matrix( size_type nWidth, size_type nHeight, const_reference rData ) { this->resize( nWidth, nHeight, rData ); }
108 :
109 : inline size_type capacity() const { return maData.capacity(); }
110 0 : inline bool empty() const { return maData.empty(); }
111 0 : inline size_type size() const { return maData.size(); }
112 0 : inline size_type width() const { return mnWidth; }
113 0 : inline size_type height() const { return this->empty() ? 0 : (this->size() / this->width()); }
114 : inline bool has( size_type nX, size_type nY ) const { return (nX < this->width()) && (nY < this->height()); }
115 :
116 : inline void reserve( size_type nWidth, size_type nHeight ) { maData.reserve( nWidth * nHeight ); }
117 0 : inline void clear() { this->resize( 0, 0 ); }
118 0 : inline void resize( size_type nWidth, size_type nHeight ) { mnWidth = nWidth; maData.resize( nWidth * nHeight ); }
119 0 : inline void resize( size_type nWidth, size_type nHeight, const_reference rData ) { mnWidth = nWidth; maData.resize( nWidth * nHeight, rData ); }
120 :
121 : inline iterator at( size_type nX, size_type nY ) { return maData.begin() + mnWidth * nY + nX; }
122 0 : inline const_iterator at( size_type nX, size_type nY ) const { return maData.begin() + mnWidth * nY + nX; }
123 :
124 : inline reference operator()( size_type nX, size_type nY ) { return *this->at( nX, nY ); }
125 0 : inline const_reference operator()( size_type nX, size_type nY ) const { return *this->at( nX, nY ); }
126 :
127 0 : inline iterator begin() { return maData.begin(); }
128 : inline const_iterator begin() const { return maData.begin(); }
129 0 : inline iterator end() { return maData.end(); }
130 : inline const_iterator end() const { return maData.end(); }
131 :
132 : inline reference front() { return maData.front(); }
133 : inline const_reference front() const { return maData.front(); }
134 : inline reference back() { return maData.back(); }
135 : inline const_reference back() const { return maData.back(); }
136 :
137 : inline iterator row_begin( size_type nY ) { return this->at( 0, nY ); }
138 0 : inline const_iterator row_begin( size_type nY ) const { return this->at( 0, nY ); }
139 : inline iterator row_end( size_type nY ) { return this->at( mnWidth, nY ); }
140 0 : inline const_iterator row_end( size_type nY ) const { return this->at( mnWidth, nY ); }
141 :
142 : inline reference row_front( size_type nY ) { return (*this)( 0, nY ); }
143 0 : inline const_reference row_front( size_type nY ) const { return (*this)( 0, nY ); }
144 : inline reference row_back( size_type nY ) { return (*this)( mnWidth - 1, nY ); }
145 : inline const_reference row_back( size_type nY ) const { return (*this)( mnWidth - 1, nY ); }
146 :
147 : inline void swap( Matrix& rMatrix ) { maData.swap( rMatrix.maData ); }
148 :
149 : private:
150 : container_type maData;
151 : size_type mnWidth;
152 : };
153 :
154 : // ============================================================================
155 :
156 : /** Static helper functions for improved API container handling. */
157 : class OOX_DLLPUBLIC ContainerHelper
158 : {
159 : public:
160 : // com.sun.star.container.XIndexContainer ---------------------------------
161 :
162 : /** Creates a new index container object from scratch. */
163 : static ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexContainer >
164 : createIndexContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext );
165 :
166 : // com.sun.star.container.XNameContainer ----------------------------------
167 :
168 : /** Creates a new name container object from scratch. */
169 : static ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >
170 : createNameContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext );
171 :
172 : /** Returns a name that is not used in the passed name container.
173 :
174 : @param rxNameAccess com.sun.star.container.XNameAccess interface of
175 : the name container.
176 :
177 : @param rSuggestedName Suggested name for the object.
178 :
179 : @return An unused name. Will be equal to the suggested name, if not
180 : contained, otherwise a numerical index will be appended.
181 : */
182 : static ::rtl::OUString getUnusedName(
183 : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& rxNameAccess,
184 : const ::rtl::OUString& rSuggestedName,
185 : sal_Unicode cSeparator,
186 : sal_Int32 nFirstIndexToAppend = 1 );
187 :
188 : /** Inserts an object into a name container.
189 :
190 : @param rxNameContainer com.sun.star.container.XNameContainer interface
191 : of the name container.
192 :
193 : @param rName Exact name for the object.
194 :
195 : @param rObject The object to be inserted.
196 :
197 : @return True = object successfully inserted.
198 : */
199 : static bool insertByName(
200 : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxNameContainer,
201 : const ::rtl::OUString& rName,
202 : const ::com::sun::star::uno::Any& rObject,
203 : bool bReplaceOldExisting = true );
204 :
205 : /** Inserts an object into a name container.
206 :
207 : The function will use an unused name to insert the object, based on the
208 : suggested object name. It is possible to specify whether the existing
209 : object or the new inserted object will be renamed, if the container
210 : already has an object with the name suggested for the new object.
211 :
212 : @param rxNameContainer com.sun.star.container.XNameContainer interface
213 : of the name container.
214 :
215 : @param rSuggestedName Suggested name for the object.
216 :
217 : @param rObject The object to be inserted.
218 :
219 : @param bRenameOldExisting Specifies behaviour if an object with the
220 : suggested name already exists. If false (default), the new object
221 : will be inserted with a name not yet extant in the container (this
222 : is done by appending a numerical index to the suggested name). If
223 : true, the existing object will be removed and inserted with an
224 : unused name, and the new object will be inserted with the suggested
225 : name.
226 :
227 : @return The final name the object is inserted with. Will always be
228 : equal to the suggested name, if parameter bRenameOldExisting is
229 : true.
230 : */
231 : static ::rtl::OUString insertByUnusedName(
232 : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& rxNameContainer,
233 : const ::rtl::OUString& rSuggestedName,
234 : sal_Unicode cSeparator,
235 : const ::com::sun::star::uno::Any& rObject,
236 : bool bRenameOldExisting = false );
237 :
238 : // std::vector and std::map element access --------------------------------
239 :
240 : /** Returns the pointer to an existing element of the passed vector, or a
241 : null pointer, if the passed index is out of bounds. */
242 : template< typename VectorType >
243 : static const typename VectorType::value_type*
244 : getVectorElement( const VectorType& rVector, sal_Int32 nIndex );
245 :
246 : /** Returns the pointer to an existing element of the passed vector, or a
247 : null pointer, if the passed index is out of bounds. */
248 : template< typename VectorType >
249 : static typename VectorType::value_type*
250 : getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex );
251 :
252 : /** Returns the reference to an existing element of the passed vector, or
253 : the passed default value, if the passed index is out of bounds. */
254 : template< typename VectorType >
255 : static const typename VectorType::value_type&
256 : getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault );
257 :
258 : /** Returns the reference to an existing element of the passed vector, or
259 : the passed default value, if the passed index is out of bounds. */
260 : template< typename VectorType >
261 : static typename VectorType::value_type&
262 : getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex, typename VectorType::value_type& rDefault );
263 :
264 : /** Returns the pointer to an existing element of the passed map, or a null
265 : pointer, if an element with the passed key does not exist. */
266 : template< typename MapType >
267 : static const typename MapType::mapped_type*
268 : getMapElement( const MapType& rMap, const typename MapType::key_type& rKey );
269 :
270 : /** Returns the pointer to an existing element of the passed map, or a null
271 : pointer, if an element with the passed key does not exist. */
272 : template< typename MapType >
273 : static typename MapType::mapped_type*
274 : getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey );
275 :
276 : /** Returns the reference to an existing element of the passed map, or the
277 : passed default value, if an element with the passed key does not exist. */
278 : template< typename MapType >
279 : static const typename MapType::mapped_type&
280 : getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault );
281 :
282 : /** Returns the reference to an existing element of the passed map, or the
283 : passed default value, if an element with the passed key does not exist. */
284 : template< typename MapType >
285 : static typename MapType::mapped_type&
286 : getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey, typename MapType::mapped_type& rDefault );
287 :
288 : // vector/map/matrix to UNO sequence --------------------------------------
289 :
290 : /** Creates a UNO sequence from a std::vector with copies of all elements.
291 :
292 : @param rVector The vector to be converted to a sequence.
293 :
294 : @return A com.sun.star.uno.Sequence object with copies of all objects
295 : contained in the passed vector.
296 : */
297 : template< typename VectorType >
298 : static ::com::sun::star::uno::Sequence< typename VectorType::value_type >
299 : vectorToSequence( const VectorType& rVector );
300 :
301 : /** Creates a UNO sequence from a std::map with copies of all elements.
302 :
303 : @param rMap The map to be converted to a sequence.
304 :
305 : @return A com.sun.star.uno.Sequence object with copies of all objects
306 : contained in the passed map.
307 : */
308 : template< typename MapType >
309 : static ::com::sun::star::uno::Sequence< typename MapType::mapped_type >
310 : mapToSequence( const MapType& rMap );
311 :
312 : /** Creates a UNO sequence of sequences from a matrix with copies of all elements.
313 :
314 : @param rMatrix The matrix to be converted to a sequence of sequences.
315 :
316 : @return A com.sun.star.uno.Sequence object containing
317 : com.sun.star.uno.Sequence objects with copies of all objects
318 : contained in the passed matrix.
319 : */
320 : template< typename MatrixType >
321 : static ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< typename MatrixType::value_type > >
322 : matrixToSequenceSequence( const MatrixType& rMatrix );
323 : };
324 :
325 : // ----------------------------------------------------------------------------
326 :
327 : template< typename VectorType >
328 66 : /*static*/ const typename VectorType::value_type* ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex )
329 : {
330 66 : return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : 0;
331 : }
332 :
333 : template< typename VectorType >
334 0 : /*static*/ typename VectorType::value_type* ContainerHelper::getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex )
335 : {
336 0 : return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? &rVector[ static_cast< size_t >( nIndex ) ] : 0;
337 : }
338 :
339 : template< typename VectorType >
340 5 : /*static*/ const typename VectorType::value_type& ContainerHelper::getVectorElement( const VectorType& rVector, sal_Int32 nIndex, const typename VectorType::value_type& rDefault )
341 : {
342 5 : return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? rVector[ static_cast< size_t >( nIndex ) ] : rDefault;
343 : }
344 :
345 : template< typename VectorType >
346 : /*static*/ typename VectorType::value_type& ContainerHelper::getVectorElementAccess( VectorType& rVector, sal_Int32 nIndex, typename VectorType::value_type& rDefault )
347 : {
348 : return ((0 <= nIndex) && (static_cast< size_t >( nIndex ) < rVector.size())) ? rVector[ static_cast< size_t >( nIndex ) ] : rDefault;
349 : }
350 :
351 : template< typename MapType >
352 2262 : /*static*/ const typename MapType::mapped_type* ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey )
353 : {
354 2262 : typename MapType::const_iterator aIt = rMap.find( rKey );
355 2262 : return (aIt == rMap.end()) ? 0 : &aIt->second;
356 : }
357 :
358 : template< typename MapType >
359 : /*static*/ typename MapType::mapped_type* ContainerHelper::getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey )
360 : {
361 : typename MapType::iterator aIt = rMap.find( rKey );
362 : return (aIt == rMap.end()) ? 0 : &aIt->second;
363 : }
364 :
365 : template< typename MapType >
366 156 : /*static*/ const typename MapType::mapped_type& ContainerHelper::getMapElement( const MapType& rMap, const typename MapType::key_type& rKey, const typename MapType::mapped_type& rDefault )
367 : {
368 156 : typename MapType::const_iterator aIt = rMap.find( rKey );
369 156 : return (aIt == rMap.end()) ? rDefault : aIt->second;
370 : }
371 :
372 : template< typename MapType >
373 : /*static*/ typename MapType::mapped_type& ContainerHelper::getMapElementAccess( MapType& rMap, const typename MapType::key_type& rKey, typename MapType::mapped_type& rDefault )
374 : {
375 : typename MapType::iterator aIt = rMap.find( rKey );
376 : return (aIt == rMap.end()) ? rDefault : aIt->second;
377 : }
378 :
379 : template< typename VectorType >
380 472 : /*static*/ ::com::sun::star::uno::Sequence< typename VectorType::value_type > ContainerHelper::vectorToSequence( const VectorType& rVector )
381 : {
382 : typedef typename VectorType::value_type ValueType;
383 472 : if( rVector.empty() )
384 171 : return ::com::sun::star::uno::Sequence< ValueType >();
385 301 : return ::com::sun::star::uno::Sequence< ValueType >( &rVector.front(), static_cast< sal_Int32 >( rVector.size() ) );
386 : }
387 :
388 : template< typename MapType >
389 : /*static*/ ::com::sun::star::uno::Sequence< typename MapType::mapped_type > ContainerHelper::mapToSequence( const MapType& rMap )
390 : {
391 : typedef typename MapType::mapped_type ValueType;
392 : if( rMap.empty() )
393 : return ::com::sun::star::uno::Sequence< ValueType >();
394 : ::com::sun::star::uno::Sequence< ValueType > aSeq( static_cast< sal_Int32 >( rMap.size() ) );
395 : sal_Int32 nIndex = 0;
396 : for( typename MapType::const_iterator aIt = rMap.begin(), aEnd = rMap.end(); aIt != aEnd; ++aIt, ++nIndex )
397 : aSeq[ nIndex ] = *aIt;
398 : return aSeq;
399 : }
400 :
401 : template< typename MatrixType >
402 0 : /*static*/ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< typename MatrixType::value_type > > ContainerHelper::matrixToSequenceSequence( const MatrixType& rMatrix )
403 : {
404 : typedef typename MatrixType::value_type ValueType;
405 0 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ValueType > > aSeq;
406 0 : if( !rMatrix.empty() )
407 : {
408 0 : aSeq.realloc( static_cast< sal_Int32 >( rMatrix.height() ) );
409 0 : for( size_t nRow = 0, nHeight = rMatrix.height(); nRow < nHeight; ++nRow )
410 0 : aSeq[ static_cast< sal_Int32 >( nRow ) ] =
411 : ::com::sun::star::uno::Sequence< ValueType >( &rMatrix.row_front( nRow ), static_cast< sal_Int32 >( rMatrix.width() ) );
412 : }
413 0 : return aSeq;
414 : }
415 :
416 : // ============================================================================
417 :
418 : } // namespace oox
419 :
420 : #endif
421 :
422 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|