/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #ifndef _COM_SUN_STAR_UNO_SEQUENCE_HXX_ #define _COM_SUN_STAR_UNO_SEQUENCE_HXX_ #include "osl/diagnose.h" #include "osl/interlck.h" #include "com/sun/star/uno/Sequence.h" #include "typelib/typedescription.h" #include "uno/data.h" #include "com/sun/star/uno/genfunc.hxx" #include "cppu/unotype.hxx" namespace com { namespace sun { namespace star { namespace uno { //______________________________________________________________________________ template< class E > typelib_TypeDescriptionReference * Sequence< E >::s_pType = 0; //______________________________________________________________________________ template< class E > inline Sequence< E >::Sequence() SAL_THROW( () ) { const Type & rType = ::cppu::getTypeFavourUnsigned( this ); ::uno_type_sequence_construct( &_pSequence, rType.getTypeLibType(), 0, 0, (uno_AcquireFunc)cpp_acquire ); // no bad_alloc, because empty sequence is statically allocated in cppu } //______________________________________________________________________________ template< class E > inline Sequence< E >::Sequence( const Sequence< E > & rSeq ) SAL_THROW( () ) { ::osl_incrementInterlockedCount( &rSeq._pSequence->nRefCount ); _pSequence = rSeq._pSequence; } //______________________________________________________________________________ template< class E > inline Sequence< E >::Sequence( uno_Sequence * pSequence, __sal_NoAcquire ) SAL_THROW( () ) : _pSequence( pSequence ) { } //______________________________________________________________________________ template< class E > inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len ) { const Type & rType = ::cppu::getTypeFavourUnsigned( this ); #if ! defined EXCEPTIONS_OFF sal_Bool success = #endif ::uno_type_sequence_construct( &_pSequence, rType.getTypeLibType(), const_cast< E * >( pElements ), len, (uno_AcquireFunc)cpp_acquire ); #if ! defined EXCEPTIONS_OFF if (! success) throw ::std::bad_alloc(); #endif } //______________________________________________________________________________ template< class E > inline Sequence< E >::Sequence( sal_Int32 len ) { const Type & rType = ::cppu::getTypeFavourUnsigned( this ); #if ! defined EXCEPTIONS_OFF sal_Bool success = #endif ::uno_type_sequence_construct( &_pSequence, rType.getTypeLibType(), 0, len, (uno_AcquireFunc)cpp_acquire ); #if ! defined EXCEPTIONS_OFF if (! success) throw ::std::bad_alloc(); #endif } //______________________________________________________________________________ template< class E > inline Sequence< E >::~Sequence() SAL_THROW( () ) { const Type & rType = ::cppu::getTypeFavourUnsigned( this ); ::uno_type_destructData( this, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release ); } //______________________________________________________________________________ template< class E > inline Sequence< E > & Sequence< E >::operator = ( const Sequence< E > & rSeq ) SAL_THROW( () ) { const Type & rType = ::cppu::getTypeFavourUnsigned( this ); ::uno_type_sequence_assign( &_pSequence, rSeq._pSequence, rType.getTypeLibType(), (uno_ReleaseFunc)cpp_release ); return *this; } //______________________________________________________________________________ template< class E > inline sal_Bool Sequence< E >::operator == ( const Sequence< E > & rSeq ) const SAL_THROW( () ) { if (_pSequence == rSeq._pSequence) return sal_True; const Type & rType = ::cppu::getTypeFavourUnsigned( this ); return ::uno_type_equalData( const_cast< Sequence< E > * >( this ), rType.getTypeLibType(), const_cast< Sequence< E > * >( &rSeq ), rType.getTypeLibType(), (uno_QueryInterfaceFunc)cpp_queryInterface, (uno_ReleaseFunc)cpp_release ); } //______________________________________________________________________________ template< class E > inline sal_Bool Sequence< E >::operator != ( const Sequence< E > & rSeq ) const SAL_THROW( () ) { return (! operator == ( rSeq )); } //______________________________________________________________________________ template< class E > inline E * Sequence< E >::getArray() { const Type & rType = ::cppu::getTypeFavourUnsigned( this ); #if ! defined EXCEPTIONS_OFF sal_Bool success = #endif ::uno_type_sequence_reference2One( &_pSequence, rType.getTypeLibType(), (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); #if ! defined EXCEPTIONS_OFF if (! success) throw ::std::bad_alloc(); #endif return reinterpret_cast< E * >( _pSequence->elements ); } //______________________________________________________________________________ template< class E > inline E & Sequence< E >::operator [] ( sal_Int32 nIndex ) { OSL_ENSURE( nIndex >= 0 && nIndex < getLength(), "### illegal index of sequence!" ); return getArray()[ nIndex ]; } //______________________________________________________________________________ template< class E > inline const E & Sequence< E >::operator [] ( sal_Int32 nIndex ) const SAL_THROW( () ) { OSL_ENSURE( nIndex >= 0 && nIndex < getLength(), "### illegal index of sequence!" ); return reinterpret_cast< const E * >( _pSequence->elements )[ nIndex ]; } //______________________________________________________________________________ template< class E > inline void Sequence< E >::realloc( sal_Int32 nSize ) { const Type & rType = ::cppu::getTypeFavourUnsigned( this ); #if !defined EXCEPTIONS_OFF sal_Bool success = #endif ::uno_type_sequence_realloc( &_pSequence, rType.getTypeLibType(), nSize, (uno_AcquireFunc)cpp_acquire, (uno_ReleaseFunc)cpp_release ); #if !defined EXCEPTIONS_OFF if (!success) throw ::std::bad_alloc(); #endif } //------------------------------------------------------------------------------ inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence( const ::rtl::ByteSequence & rByteSequence ) SAL_THROW( () ) { return ::com::sun::star::uno::Sequence< sal_Int8 >( * reinterpret_cast< const ::com::sun::star::uno::Sequence< sal_Int8 > * >( &rByteSequence ) ); } } } } } namespace cppu { template< typename T > inline ::com::sun::star::uno::Type const & getTypeFavourUnsigned(::com::sun::star::uno::Sequence< T > const *) { if (::com::sun::star::uno::Sequence< T >::s_pType == 0) { ::typelib_static_sequence_type_init( &::com::sun::star::uno::Sequence< T >::s_pType, (::cppu::getTypeFavourUnsigned( static_cast< typename ::com::sun::star::uno::Sequence< T >::ElementType * >( 0)). getTypeLibType())); } return detail::getTypeFromTypeDescriptionReference( &::com::sun::star::uno::Sequence< T >::s_pType); } template< typename T > inline ::com::sun::star::uno::Type const & getTypeFavourChar(::com::sun::star::uno::Sequence< T > const *) { //TODO On certain platforms with weak memory models, the following code can // result in some threads observing that td points to garbage: static typelib_TypeDescriptionReference * td = 0; if (td == 0) { ::typelib_static_sequence_type_init( &td, (::cppu::getTypeFavourChar( static_cast< typename ::com::sun::star::uno::Sequence< T >::ElementType * >( 0)). getTypeLibType())); } return detail::getTypeFromTypeDescriptionReference(&td); } } // generic sequence template template< class E > inline const ::com::sun::star::uno::Type & SAL_CALL getCppuType( const ::com::sun::star::uno::Sequence< E > * ) SAL_THROW( () ) { return ::cppu::getTypeFavourUnsigned( static_cast< ::com::sun::star::uno::Sequence< E > * >(0)); } // generic sequence template for given element type (e.g. C++ arrays) template< class E > inline const ::com::sun::star::uno::Type & SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType ) SAL_THROW( () ) { if (! ::com::sun::star::uno::Sequence< E >::s_pType) { ::typelib_static_sequence_type_init( & ::com::sun::star::uno::Sequence< E >::s_pType, rElementType.getTypeLibType() ); } return * reinterpret_cast< const ::com::sun::star::uno::Type * >( & ::com::sun::star::uno::Sequence< E >::s_pType ); } #if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0; #endif // char sequence inline const ::com::sun::star::uno::Type & SAL_CALL getCharSequenceCppuType() SAL_THROW( () ) { #if !( defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0; #endif if (! s_pType_com_sun_star_uno_Sequence_Char) { const ::com::sun::star::uno::Type & rElementType = ::getCharCppuType(); ::typelib_static_sequence_type_init( & s_pType_com_sun_star_uno_Sequence_Char, rElementType.getTypeLibType() ); } return * reinterpret_cast< const ::com::sun::star::uno::Type * >( & s_pType_com_sun_star_uno_Sequence_Char ); } #endif