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