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