Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 : #ifndef INCLUDED_COM_SUN_STAR_UNO_SEQUENCE_HXX
20 : #define INCLUDED_COM_SUN_STAR_UNO_SEQUENCE_HXX
21 :
22 : #include <sal/config.h>
23 :
24 : #include <cassert>
25 :
26 : #include <osl/interlck.h>
27 : #include <com/sun/star/uno/Sequence.h>
28 : #include <typelib/typedescription.h>
29 : #include <uno/data.h>
30 : #include <com/sun/star/uno/genfunc.hxx>
31 : #include <cppu/unotype.hxx>
32 :
33 : namespace com
34 : {
35 : namespace sun
36 : {
37 : namespace star
38 : {
39 : namespace uno
40 : {
41 :
42 : /// @cond INTERNAL
43 : template< class E >
44 : typelib_TypeDescriptionReference * Sequence< E >::s_pType = 0;
45 : /// @endcond
46 :
47 : template< class E >
48 114764984 : inline Sequence< E >::Sequence()
49 : {
50 114764984 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
51 114764984 : ::uno_type_sequence_construct(
52 : &_pSequence, rType.getTypeLibType(),
53 114764984 : 0, 0, cpp_acquire );
54 : // no bad_alloc, because empty sequence is statically allocated in cppu
55 114764984 : }
56 :
57 : template< class E >
58 8349353 : inline Sequence< E >::Sequence( const Sequence< E > & rSeq )
59 : {
60 8349353 : osl_atomic_increment( &rSeq._pSequence->nRefCount );
61 8349353 : _pSequence = rSeq._pSequence;
62 8349353 : }
63 :
64 : template< class E >
65 15 : inline Sequence< E >::Sequence(
66 : uno_Sequence * pSequence, __sal_NoAcquire )
67 15 : : _pSequence( pSequence )
68 : {
69 15 : }
70 :
71 : template< class E >
72 29987217 : inline Sequence< E >::Sequence( const E * pElements, sal_Int32 len )
73 : {
74 29987217 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
75 : bool success =
76 : ::uno_type_sequence_construct(
77 : &_pSequence, rType.getTypeLibType(),
78 29987217 : const_cast< E * >( pElements ), len, cpp_acquire );
79 29987217 : if (! success)
80 0 : throw ::std::bad_alloc();
81 29987217 : }
82 :
83 : template< class E >
84 235978798 : inline Sequence< E >::Sequence( sal_Int32 len )
85 : {
86 235978798 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
87 : bool success =
88 : ::uno_type_sequence_construct(
89 : &_pSequence, rType.getTypeLibType(),
90 235978798 : 0, len, cpp_acquire );
91 235978798 : if (! success)
92 0 : throw ::std::bad_alloc();
93 235978798 : }
94 :
95 : #if defined LIBO_INTERNAL_ONLY
96 3267 : template<typename E> Sequence<E>::Sequence(std::initializer_list<E> init) {
97 3267 : if (!uno_type_sequence_construct(
98 3267 : &_pSequence, cppu::getTypeFavourUnsigned(this).getTypeLibType(),
99 6534 : const_cast<E *>(init.begin()), init.size(), cpp_acquire))
100 : {
101 0 : throw std::bad_alloc();
102 : }
103 3267 : }
104 : #endif
105 :
106 : template< class E >
107 389027647 : inline Sequence< E >::~Sequence()
108 : {
109 389027647 : if (osl_atomic_decrement( &_pSequence->nRefCount ) == 0)
110 : {
111 235262998 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
112 235262997 : uno_type_sequence_destroy(
113 235262998 : _pSequence, rType.getTypeLibType(), cpp_release );
114 : }
115 389027649 : }
116 :
117 : template< class E >
118 7935918 : inline Sequence< E > & Sequence< E >::operator = ( const Sequence< E > & rSeq )
119 : {
120 7935918 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
121 7935918 : ::uno_type_sequence_assign(
122 7935918 : &_pSequence, rSeq._pSequence, rType.getTypeLibType(), cpp_release );
123 7935918 : return *this;
124 : }
125 :
126 : template< class E >
127 244246 : inline bool Sequence< E >::operator == ( const Sequence< E > & rSeq ) const
128 : {
129 244246 : if (_pSequence == rSeq._pSequence)
130 133480 : return true;
131 110766 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
132 : return ::uno_type_equalData(
133 : const_cast< Sequence< E > * >( this ), rType.getTypeLibType(),
134 : const_cast< Sequence< E > * >( &rSeq ), rType.getTypeLibType(),
135 : cpp_queryInterface,
136 110766 : cpp_release );
137 : }
138 :
139 : template< class E >
140 313 : inline bool Sequence< E >::operator != ( const Sequence< E > & rSeq ) const
141 : {
142 313 : return (! operator == ( rSeq ));
143 : }
144 :
145 : template< class E >
146 320326650 : inline E * Sequence< E >::getArray()
147 : {
148 320326650 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
149 : bool success =
150 : ::uno_type_sequence_reference2One(
151 : &_pSequence, rType.getTypeLibType(),
152 320326650 : cpp_acquire, cpp_release );
153 320326650 : if (! success)
154 0 : throw ::std::bad_alloc();
155 320326650 : return reinterpret_cast< E * >( _pSequence->elements );
156 : }
157 :
158 227074 : template<class E> E * Sequence<E>::begin() { return getArray(); }
159 :
160 1923762 : template<class E> E const * Sequence<E>::begin() const
161 1923762 : { return getConstArray(); }
162 :
163 144281 : template<class E> E * Sequence<E>::end() { return begin() + getLength(); }
164 :
165 963006 : template<class E> E const * Sequence<E>::end() const
166 963006 : { return begin() + getLength(); }
167 :
168 : template< class E >
169 109317319 : inline E & Sequence< E >::operator [] ( sal_Int32 nIndex )
170 : {
171 : // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2
172 : assert(nIndex >= 0 && static_cast<sal_uInt32>(nIndex) < static_cast<sal_uInt32>(getLength()));
173 109317319 : return getArray()[ nIndex ];
174 : }
175 :
176 : template< class E >
177 81606337 : inline const E & Sequence< E >::operator [] ( sal_Int32 nIndex ) const
178 : {
179 : // silence spurious -Werror=strict-overflow warnings from GCC 4.8.2
180 : assert(nIndex >= 0 && static_cast<sal_uInt32>(nIndex) < static_cast<sal_uInt32>(getLength()));
181 81606337 : return reinterpret_cast< const E * >( _pSequence->elements )[ nIndex ];
182 : }
183 :
184 : template< class E >
185 9616642 : inline void Sequence< E >::realloc( sal_Int32 nSize )
186 : {
187 9616642 : const Type & rType = ::cppu::getTypeFavourUnsigned( this );
188 : bool success =
189 : ::uno_type_sequence_realloc(
190 : &_pSequence, rType.getTypeLibType(), nSize,
191 9616642 : cpp_acquire, cpp_release );
192 9616642 : if (!success)
193 0 : throw ::std::bad_alloc();
194 9616642 : }
195 :
196 660 : inline ::com::sun::star::uno::Sequence< sal_Int8 > SAL_CALL toUnoSequence(
197 : const ::rtl::ByteSequence & rByteSequence )
198 : {
199 : return ::com::sun::star::uno::Sequence< sal_Int8 >(
200 660 : * reinterpret_cast< const ::com::sun::star::uno::Sequence< sal_Int8 > * >( &rByteSequence ) );
201 : }
202 :
203 : }
204 : }
205 : }
206 : }
207 :
208 : namespace cppu {
209 :
210 : template< typename T > inline ::com::sun::star::uno::Type const &
211 958768568 : getTypeFavourUnsigned(
212 : SAL_UNUSED_PARAMETER ::com::sun::star::uno::Sequence< T > const *)
213 : {
214 958768568 : if (::com::sun::star::uno::Sequence< T >::s_pType == 0) {
215 37615 : ::typelib_static_sequence_type_init(
216 : &::com::sun::star::uno::Sequence< T >::s_pType,
217 : (::cppu::getTypeFavourUnsigned(
218 : static_cast<
219 : typename ::com::sun::star::uno::Sequence< T >::ElementType * >(
220 37615 : 0)).
221 37615 : getTypeLibType()));
222 : }
223 : return detail::getTypeFromTypeDescriptionReference(
224 958768568 : &::com::sun::star::uno::Sequence< T >::s_pType);
225 : }
226 :
227 : template< typename T > inline ::com::sun::star::uno::Type const &
228 45 : getTypeFavourChar(
229 : SAL_UNUSED_PARAMETER ::com::sun::star::uno::Sequence< T > const *)
230 : {
231 : //TODO On certain platforms with weak memory models, the following code can
232 : // result in some threads observing that td points to garbage:
233 : static typelib_TypeDescriptionReference * td = 0;
234 45 : if (td == 0) {
235 36 : ::typelib_static_sequence_type_init(
236 : &td,
237 : (::cppu::getTypeFavourChar(
238 : static_cast<
239 : typename ::com::sun::star::uno::Sequence< T >::ElementType * >(
240 36 : 0)).
241 36 : getTypeLibType()));
242 : }
243 45 : return detail::getTypeFromTypeDescriptionReference(&td);
244 : }
245 :
246 : }
247 :
248 : // generic sequence template
249 : template< class E >
250 : inline const ::com::sun::star::uno::Type &
251 : SAL_CALL getCppuType(
252 : SAL_UNUSED_PARAMETER const ::com::sun::star::uno::Sequence< E > * )
253 : {
254 : return ::cppu::getTypeFavourUnsigned(
255 : static_cast< ::com::sun::star::uno::Sequence< E > * >(0));
256 : }
257 :
258 : // generic sequence template for given element type (e.g. C++ arrays)
259 : template< class E >
260 : inline const ::com::sun::star::uno::Type &
261 : SAL_CALL getCppuSequenceType( const ::com::sun::star::uno::Type & rElementType )
262 : {
263 : if (! ::com::sun::star::uno::Sequence< E >::s_pType)
264 : {
265 : ::typelib_static_sequence_type_init(
266 : & ::com::sun::star::uno::Sequence< E >::s_pType,
267 : rElementType.getTypeLibType() );
268 : }
269 : return * reinterpret_cast< const ::com::sun::star::uno::Type * >(
270 : & ::com::sun::star::uno::Sequence< E >::s_pType );
271 : }
272 :
273 : // char sequence
274 : inline const ::com::sun::star::uno::Type &
275 : SAL_CALL getCharSequenceCppuType()
276 : {
277 : static typelib_TypeDescriptionReference * s_pType_com_sun_star_uno_Sequence_Char = 0;
278 : if (! s_pType_com_sun_star_uno_Sequence_Char)
279 : {
280 : const ::com::sun::star::uno::Type & rElementType = cppu::UnoType<cppu::UnoCharType>::get();
281 : ::typelib_static_sequence_type_init(
282 : & s_pType_com_sun_star_uno_Sequence_Char,
283 : rElementType.getTypeLibType() );
284 : }
285 : return * reinterpret_cast< const ::com::sun::star::uno::Type * >(
286 : & s_pType_com_sun_star_uno_Sequence_Char );
287 : }
288 :
289 : #endif
290 :
291 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|