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 #ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_ 28 #define _COM_SUN_STAR_UNO_SEQUENCE_HXX_ 29 30 #include "osl/diagnose.h" 31 #include "osl/interlck.h" 32 #include "com/sun/star/uno/Sequence.h" 33 #include "typelib/typedescription.h" 34 #include "uno/data.h" 35 #include "com/sun/star/uno/genfunc.hxx" 36 #include "cppu/unotype.hxx" 37 38 namespace com 39 { 40 namespace sun 41 { 42 namespace star 43 { 44 namespace uno 45 { 46 47 //______________________________________________________________________________ 48 template< class E > 49 typelib_TypeDescriptionReference * Sequence< E >::s_pType = 0; 50 51 //______________________________________________________________________________ 52 template< class E > 53 inline Sequence< E >::Sequence() SAL_THROW( () ) 54 { 55 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 56 ::uno_type_sequence_construct( 57 &_pSequence, rType.getTypeLibType(), 58 0, 0, (uno_AcquireFunc)cpp_acquire ); 59 // no bad_alloc, because empty sequence is statically allocated in cppu 60 } 61 62 //______________________________________________________________________________ 63 template< class E > 64 inline Sequence< E >::Sequence( const Sequence< E > & rSeq ) SAL_THROW( () ) 65 { 66 ::osl_incrementInterlockedCount( &rSeq._pSequence->nRefCount ); 67 _pSequence = rSeq._pSequence; 68 } 69 70 //______________________________________________________________________________ 71 template< class E > 72 inline Sequence< E >::Sequence( 73 uno_Sequence * pSequence, __sal_NoAcquire ) SAL_THROW( () ) 74 : _pSequence( pSequence ) 75 { 76 } 77 78 //______________________________________________________________________________ 79 template< class E > 80 inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len ) 81 { 82 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 83 #if ! defined EXCEPTIONS_OFF 84 sal_Bool success = 85 #endif 86 ::uno_type_sequence_construct( 87 &_pSequence, rType.getTypeLibType(), 88 const_cast< E * >( pElements ), len, (uno_AcquireFunc)cpp_acquire ); 89 #if ! defined EXCEPTIONS_OFF 90 if (! success) 91 throw ::std::bad_alloc(); 92 #endif 93 } 94 95 //______________________________________________________________________________ 96 template< class E > 97 inline Sequence< E >::Sequence( sal_Int32 len ) 98 { 99 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 100 #if ! defined EXCEPTIONS_OFF 101 sal_Bool success = 102 #endif 103 ::uno_type_sequence_construct( 104 &_pSequence, rType.getTypeLibType(), 105 0, len, (uno_AcquireFunc)cpp_acquire ); 106 #if ! defined EXCEPTIONS_OFF 107 if (! success) 108 throw ::std::bad_alloc(); 109 #endif 110 } 111 112 //______________________________________________________________________________ 113 template< class E > 114 inline Sequence< E >::~Sequence() SAL_THROW( () ) 115 { 116 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 117 ::uno_type_destructData( 118 this, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release ); 119 } 120 121 //______________________________________________________________________________ 122 template< class E > 123 inline Sequence< E > & Sequence< E >::operator = ( const Sequence< E > & rSeq ) SAL_THROW( () ) 124 { 125 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 126 ::uno_type_sequence_assign( 127 &_pSequence, rSeq._pSequence, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release ); 128 return *this; 129 } 130 131 //______________________________________________________________________________ 132 template< class E > 133 inline sal_Bool Sequence< E >::operator == ( const Sequence< E > & rSeq ) const 134 SAL_THROW( () ) 135 { 136 if (_pSequence == rSeq._pSequence) 137 return sal_True; 138 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 139 return ::uno_type_equalData( 140 const_cast< Sequence< E > * >( this ), rType.getTypeLibType(), 141 const_cast< Sequence< E > * >( &rSeq ), rType.getTypeLibType(), 142 (uno_QueryInterfaceFunc)cpp_queryInterface, 143 (uno_ReleaseFunc)cpp_release ); 144 } 145 146 //______________________________________________________________________________ 147 template< class E > 148 inline sal_Bool Sequence< E >::operator != ( const Sequence< E > & rSeq ) const 149 SAL_THROW( () ) 150 { 151 return (! operator == ( rSeq )); 152 } 153 154 //______________________________________________________________________________ 155 template< class E > 156 inline E * Sequence< E >::getArray() 157 { 158 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 159 #if ! defined EXCEPTIONS_OFF 160 sal_Bool success = 161 #endif 162 ::uno_type_sequence_reference2One( 163 &_pSequence, rType.getTypeLibType(), 164 (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); 165 #if ! defined EXCEPTIONS_OFF 166 if (! success) 167 throw ::std::bad_alloc(); 168 #endif 169 return reinterpret_cast< E * >( _pSequence->elements ); 170 } 171 172 //______________________________________________________________________________ 173 template< class E > 174 inline E & Sequence< E >::operator [] ( sal_Int32 nIndex ) 175 { 176 OSL_ENSURE( 177 nIndex >= 0 && nIndex < getLength(), 178 "### illegal index of sequence!" ); 179 return getArray()[ nIndex ]; 180 } 181 182 //______________________________________________________________________________ 183 template< class E > 184 inline const E & Sequence< E >::operator [] ( sal_Int32 nIndex ) const 185 SAL_THROW( () ) 186 { 187 OSL_ENSURE( 188 nIndex >= 0 && nIndex < getLength(), 189 "### illegal index of sequence!" ); 190 return reinterpret_cast< const E * >( _pSequence->elements )[ nIndex ]; 191 } 192 193 //______________________________________________________________________________ 194 template< class E > 195 inline void Sequence< E >::realloc( sal_Int32 nSize ) 196 { 197 const Type & rType = ::cppu::getTypeFavourUnsigned( this ); 198 #if !defined EXCEPTIONS_OFF 199 sal_Bool success = 200 #endif 201 ::uno_type_sequence_realloc( 202 &_pSequence, rType.getTypeLibType(), nSize, 203 (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); 204 #if !defined EXCEPTIONS_OFF 205 if (!success) 206 throw ::std::bad_alloc(); 207 #endif 208 } 209 210 //------------------------------------------------------------------------------ 211 inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence( 212 const ::rtl::ByteSequence & rByteSequence ) SAL_THROW( () ) 213 { 214 return ::com::sun::star::uno::Sequence< sal_Int8 >( 215 * reinterpret_cast< const ::com::sun::star::uno::Sequence< sal_Int8 > * >( &rByteSequence ) ); 216 } 217 218 } 219 } 220 } 221 } 222 223 namespace cppu { 224 225 template< typename T > inline ::com::sun::star::uno::Type const & 226 getTypeFavourUnsigned(::com::sun::star::uno::Sequence< T > const *) { 227 if (::com::sun::star::uno::Sequence< T >::s_pType == 0) { 228 ::typelib_static_sequence_type_init( 229 &::com::sun::star::uno::Sequence< T >::s_pType, 230 (::cppu::getTypeFavourUnsigned( 231 static_cast< 232 typename ::com::sun::star::uno::Sequence< T >::ElementType * >( 233 0)). 234 getTypeLibType())); 235 } 236 return detail::getTypeFromTypeDescriptionReference( 237 &::com::sun::star::uno::Sequence< T >::s_pType); 238 } 239 240 template< typename T > inline ::com::sun::star::uno::Type const & 241 getTypeFavourChar(::com::sun::star::uno::Sequence< T > const *) { 242 //TODO On certain platforms with weak memory models, the following code can 243 // result in some threads observing that td points to garbage: 244 static typelib_TypeDescriptionReference * td = 0; 245 if (td == 0) { 246 ::typelib_static_sequence_type_init( 247 &td, 248 (::cppu::getTypeFavourChar( 249 static_cast< 250 typename ::com::sun::star::uno::Sequence< T >::ElementType * >( 251 0)). 252 getTypeLibType())); 253 } 254 return detail::getTypeFromTypeDescriptionReference(&td); 255 } 256 257 } 258 259 // generic sequence template 260 template< class E > 261 inline const ::com::sun::star::uno::Type & 262 SAL_CALL getCppuType( const ::com::sun::star::uno::Sequence< E > * ) 263 SAL_THROW( () ) 264 { 265 return ::cppu::getTypeFavourUnsigned( 266 static_cast< ::com::sun::star::uno::Sequence< E > * >(0)); 267 } 268 269 // generic sequence template for given element type (e.g. C++ arrays) 270 template< class E > 271 inline const ::com::sun::star::uno::Type & 272 SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType ) 273 SAL_THROW( () ) 274 { 275 if (! ::com::sun::star::uno::Sequence< E >::s_pType) 276 { 277 ::typelib_static_sequence_type_init( 278 & ::com::sun::star::uno::Sequence< E >::s_pType, 279 rElementType.getTypeLibType() ); 280 } 281 return * reinterpret_cast< const ::com::sun::star::uno::Type * >( 282 & ::com::sun::star::uno::Sequence< E >::s_pType ); 283 } 284 285 #if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) 286 static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0; 287 #endif 288 289 // char sequence 290 inline const ::com::sun::star::uno::Type & 291 SAL_CALL getCharSequenceCppuType() SAL_THROW( () ) 292 { 293 #if !( defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) 294 static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0; 295 #endif 296 if (! s_pType_com_sun_star_uno_Sequence_Char) 297 { 298 const ::com::sun::star::uno::Type & rElementType = ::getCharCppuType(); 299 ::typelib_static_sequence_type_init( 300 & s_pType_com_sun_star_uno_Sequence_Char, 301 rElementType.getTypeLibType() ); 302 } 303 return * reinterpret_cast< const ::com::sun::star::uno::Type * >( 304 & s_pType_com_sun_star_uno_Sequence_Char ); 305 } 306 307 #endif 308