xref: /aoo41x/main/cppu/inc/com/sun/star/uno/Sequence.hxx (revision cdf0e10c)
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