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