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