Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "rtl/instance.hxx"
31 : : #include "osl/diagnose.h"
32 : : #include "osl/doublecheckedlocking.h"
33 : : #include "osl/mutex.hxx"
34 : : #include "uno/dispatcher.hxx"
35 : : #include "uno/mapping.hxx"
36 : : #include "cppuhelper/detail/XExceptionThrower.hpp"
37 : : #include "com/sun/star/uno/RuntimeException.hpp"
38 : :
39 : : #include "cppuhelper/exc_hlp.hxx"
40 : :
41 : : #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
42 : :
43 : :
44 : : using namespace ::rtl;
45 : : using namespace ::osl;
46 : : using namespace ::cppu;
47 : : using namespace ::com::sun::star;
48 : : using namespace ::com::sun::star::uno;
49 : :
50 : : namespace
51 : : {
52 : :
53 : : using cppuhelper::detail::XExceptionThrower;
54 : :
55 : : //==============================================================================
56 : : struct ExceptionThrower : public uno_Interface, XExceptionThrower
57 : : {
58 : : inline ExceptionThrower();
59 : :
60 [ - + ]: 267 : virtual ~ExceptionThrower() {}
61 : :
62 : 20135 : static inline Type const & getCppuType()
63 : : {
64 : : return ::getCppuType(
65 : 20135 : reinterpret_cast< Reference< XExceptionThrower > const * >(0) );
66 : : }
67 : :
68 : : // XInterface
69 : : virtual Any SAL_CALL queryInterface( Type const & type )
70 : : throw (RuntimeException);
71 : : virtual void SAL_CALL acquire() throw ();
72 : : virtual void SAL_CALL release() throw ();
73 : :
74 : : // XExceptionThrower
75 : : virtual void SAL_CALL throwException( Any const & exc ) throw (Exception);
76 : : virtual void SAL_CALL rethrowException() throw (Exception);
77 : : };
78 : :
79 : : extern "C"
80 : : {
81 : :
82 : : //------------------------------------------------------------------------------
83 : 103674 : static void SAL_CALL ExceptionThrower_acquire_release_nop(
84 : : SAL_UNUSED_PARAMETER uno_Interface * )
85 : 103674 : {}
86 : :
87 : : //------------------------------------------------------------------------------
88 : 34558 : static void SAL_CALL ExceptionThrower_dispatch(
89 : : uno_Interface * pUnoI, typelib_TypeDescription const * pMemberType,
90 : : void * pReturn, void * pArgs [], uno_Any ** ppException )
91 : : {
92 : : OSL_ASSERT( pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD );
93 : :
94 [ + - + - ]: 34558 : switch (reinterpret_cast< typelib_InterfaceMemberTypeDescription * >(
95 : : const_cast< typelib_TypeDescription * >( pMemberType ) )->
96 : : nPosition)
97 : : {
98 : : case 0: // queryInterace()
99 : : {
100 : : Type const & rType_demanded =
101 : 17279 : *reinterpret_cast< Type const * >( pArgs[ 0 ] );
102 [ + - ]: 17279 : if (rType_demanded.equals(
[ - + # # ]
103 : : ::getCppuType( reinterpret_cast<
104 : 17279 : Reference< XInterface > const * >(0) ) ) ||
105 : 0 : rType_demanded.equals( ExceptionThrower::getCppuType() ))
106 : : {
107 : 17279 : typelib_TypeDescription * pTD = 0;
108 [ + - ][ - + ]: 17279 : TYPELIB_DANGER_GET( &pTD, rType_demanded.getTypeLibType() );
[ + - ][ - + ]
[ # # ]
109 : : uno_any_construct(
110 : 17279 : reinterpret_cast< uno_Any * >( pReturn ), &pUnoI, pTD, 0 );
111 [ - + ][ + - ]: 17279 : TYPELIB_DANGER_RELEASE( pTD );
112 : : }
113 : : else
114 : : {
115 : : uno_any_construct(
116 : 0 : reinterpret_cast< uno_Any * >( pReturn ), 0, 0, 0 );
117 : : }
118 : 17279 : *ppException = 0;
119 : 17279 : break;
120 : : }
121 : : case 1: // acquire()
122 : : case 2: // release()
123 : 0 : *ppException = 0;
124 : 0 : break;
125 : : case 3: // throwException()
126 : : {
127 : 17279 : uno_Any * pAny = reinterpret_cast< uno_Any * >( pArgs[ 0 ] );
128 : : OSL_ASSERT( pAny->pType->eTypeClass == typelib_TypeClass_EXCEPTION );
129 : 17279 : uno_type_any_construct( *ppException, pAny->pData, pAny->pType, 0 );
130 : 17279 : break;
131 : : }
132 : : default:
133 : : {
134 : : OSL_ASSERT( 0 );
135 : : RuntimeException exc(
136 [ # # ][ # # ]: 0 : OUSTR("not implemented!"), Reference< XInterface >() );
137 : : uno_type_any_construct(
138 [ # # ]: 0 : *ppException, &exc, ::getCppuType( &exc ).getTypeLibType(), 0 );
139 [ # # ]: 0 : break;
140 : : }
141 : : }
142 : 34558 : }
143 : :
144 : : } // extern "C"
145 : :
146 : : //______________________________________________________________________________
147 : 2856 : Any ExceptionThrower::queryInterface( Type const & type )
148 : : throw (RuntimeException)
149 : : {
150 [ + - ]: 2856 : if (type.equals( ::getCppuType( reinterpret_cast<
[ - + # # ]
151 : 2856 : Reference< XInterface > const * >(0) ) ) ||
152 : 0 : type.equals( ExceptionThrower::getCppuType() ))
153 : : {
154 : 2856 : XExceptionThrower * that = static_cast< XExceptionThrower * >( this );
155 : 2856 : return Any( &that, type );
156 : : }
157 : 2856 : return Any();
158 : : }
159 : :
160 : : //______________________________________________________________________________
161 : 8568 : void ExceptionThrower::acquire() throw ()
162 : : {
163 : 8568 : }
164 : : //______________________________________________________________________________
165 : 8568 : void ExceptionThrower::release() throw ()
166 : : {
167 : 8568 : }
168 : :
169 : : //______________________________________________________________________________
170 : 0 : void ExceptionThrower::throwException( Any const & exc ) throw (Exception)
171 : : {
172 : : OSL_FAIL( "unexpected!" );
173 : 0 : throwException( exc );
174 : 0 : }
175 : :
176 : : //______________________________________________________________________________
177 : 2856 : void ExceptionThrower::rethrowException() throw (Exception)
178 : : {
179 : 2856 : throw;
180 : : }
181 : :
182 : : //______________________________________________________________________________
183 : 267 : inline ExceptionThrower::ExceptionThrower()
184 : : {
185 : 267 : uno_Interface::acquire = ExceptionThrower_acquire_release_nop;
186 : 267 : uno_Interface::release = ExceptionThrower_acquire_release_nop;
187 : 267 : uno_Interface::pDispatcher = ExceptionThrower_dispatch;
188 : 267 : }
189 : :
190 : : class theExceptionThrower : public rtl::Static<ExceptionThrower, theExceptionThrower> {};
191 : :
192 : : } // anonymous namespace
193 : :
194 : :
195 : : namespace cppu
196 : : {
197 : :
198 : : //==============================================================================
199 : 17279 : void SAL_CALL throwException( Any const & exc ) SAL_THROW( (Exception) )
200 : : {
201 [ - + ]: 17279 : if (exc.getValueTypeClass() != TypeClass_EXCEPTION)
202 : : {
203 : : throw RuntimeException(
204 : : OUSTR("no UNO exception given "
205 : : "(must be derived from com::sun::star::uno::Exception)!"),
206 [ # # ][ # # ]: 0 : Reference< XInterface >() );
207 : : }
208 : :
209 [ + - ][ + - ]: 17279 : Mapping uno2cpp(Environment(OUSTR(UNO_LB_UNO)), Environment::getCurrent());
[ + - ][ + - ]
[ + - ]
210 [ - + ]: 17279 : if (! uno2cpp.is())
211 : : {
212 : : throw RuntimeException(
213 : : OUSTR("cannot get binary UNO to C++ mapping!"),
214 [ # # ][ # # ]: 0 : Reference< XInterface >() );
215 : : }
216 : :
217 : 17279 : Reference< XExceptionThrower > xThrower;
218 : : uno2cpp.mapInterface(
219 : : reinterpret_cast< void ** >( &xThrower ),
220 [ + - ]: 17279 : static_cast< uno_Interface * >( &theExceptionThrower::get() ),
221 [ + - ][ + - ]: 34558 : ExceptionThrower::getCppuType() );
222 : : OSL_ASSERT( xThrower.is() );
223 [ + - ][ - + ]: 17279 : xThrower->throwException( exc );
[ # # ]
224 : 0 : }
225 : :
226 : : //==============================================================================
227 : 2856 : Any SAL_CALL getCaughtException()
228 : : {
229 [ + - ][ + - ]: 2856 : Mapping cpp2uno(Environment::getCurrent(), Environment(OUSTR(UNO_LB_UNO)));
[ + - ][ + - ]
[ + - ]
230 [ - + ]: 2856 : if (! cpp2uno.is())
231 : : {
232 : : throw RuntimeException(
233 : : OUSTR("cannot get C++ to binary UNO mapping!"),
234 [ # # ][ # # ]: 0 : Reference< XInterface >() );
235 : : }
236 [ + - ][ + - ]: 2856 : Mapping uno2cpp(Environment(OUSTR(UNO_LB_UNO)), Environment::getCurrent());
[ + - ][ + - ]
[ + - ]
237 [ - + ]: 2856 : if (! uno2cpp.is())
238 : : {
239 : : throw RuntimeException(
240 : : OUSTR("cannot get binary UNO to C++ mapping!"),
241 [ # # ][ # # ]: 0 : Reference< XInterface >() );
242 : : }
243 : :
244 : 2856 : typelib_TypeDescription * pTD = 0;
245 [ + - ][ + - ]: 2856 : TYPELIB_DANGER_GET(
[ - + ][ + - ]
[ - + ][ # # ]
246 : : &pTD, ExceptionThrower::getCppuType().getTypeLibType() );
247 : :
248 : 2856 : UnoInterfaceReference unoI;
249 : : cpp2uno.mapInterface(
250 : : reinterpret_cast< void ** >( &unoI.m_pUnoI ),
251 [ + - ]: 2856 : static_cast< XExceptionThrower * >( &theExceptionThrower::get() ), pTD );
252 : : OSL_ASSERT( unoI.is() );
253 : :
254 : 2856 : typelib_TypeDescription * pMemberTD = 0;
255 [ - + ][ # # ]: 2856 : TYPELIB_DANGER_GET(
[ # # ][ # # ]
[ # # ]
256 : : &pMemberTD,
257 : : reinterpret_cast< typelib_InterfaceTypeDescription * >( pTD )->
258 : : ppMembers[ 1 ] /* rethrowException() */ );
259 : :
260 : : uno_Any exc_mem;
261 : 2856 : uno_Any * exc = &exc_mem;
262 [ + - ]: 2856 : unoI.dispatch( pMemberTD, 0, 0, &exc );
263 : :
264 [ - + ][ # # ]: 2856 : TYPELIB_DANGER_RELEASE( pMemberTD );
265 [ + - ][ - + ]: 2856 : TYPELIB_DANGER_RELEASE( pTD );
266 : :
267 [ - + ]: 2856 : if (exc == 0)
268 : : {
269 : : throw RuntimeException(
270 : : OUSTR("rethrowing C++ exception failed!"),
271 [ # # ][ # # ]: 0 : Reference< XInterface >() );
272 : : }
273 : :
274 : 2856 : Any ret;
275 : 2856 : uno_any_destruct( &ret, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
276 : : uno_type_any_constructAndConvert(
277 : 2856 : &ret, exc->pData, exc->pType, uno2cpp.get() );
278 : 2856 : uno_any_destruct( exc, 0 );
279 [ + - ][ + - ]: 2856 : return ret;
[ + - ]
280 : : }
281 : :
282 : : }
283 : :
284 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|