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