update credits
[LibreOffice.git] / cppuhelper / source / exc_thrower.cxx
blobd63b9bed8c38c57323432f9c6d224cfa869d9c61
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "rtl/instance.hxx"
22 #include "osl/diagnose.h"
23 #include "osl/doublecheckedlocking.h"
24 #include "osl/mutex.hxx"
25 #include "uno/dispatcher.hxx"
26 #include "uno/mapping.hxx"
27 #include "cppuhelper/detail/XExceptionThrower.hpp"
28 #include "com/sun/star/uno/RuntimeException.hpp"
30 #include "cppuhelper/exc_hlp.hxx"
33 using namespace ::rtl;
34 using namespace ::osl;
35 using namespace ::cppu;
36 using namespace ::com::sun::star;
37 using namespace ::com::sun::star::uno;
39 namespace
42 using cppuhelper::detail::XExceptionThrower;
44 //==============================================================================
45 struct ExceptionThrower : public uno_Interface, XExceptionThrower
47 inline ExceptionThrower();
49 virtual ~ExceptionThrower() {}
51 static inline Type const & getCppuType()
53 return ::getCppuType(
54 reinterpret_cast< Reference< XExceptionThrower > const * >(0) );
57 // XInterface
58 virtual Any SAL_CALL queryInterface( Type const & type )
59 throw (RuntimeException);
60 virtual void SAL_CALL acquire() throw ();
61 virtual void SAL_CALL release() throw ();
63 // XExceptionThrower
64 virtual void SAL_CALL throwException( Any const & exc ) throw (Exception);
65 virtual void SAL_CALL rethrowException() throw (Exception);
68 extern "C"
71 //------------------------------------------------------------------------------
72 static void SAL_CALL ExceptionThrower_acquire_release_nop(
73 SAL_UNUSED_PARAMETER uno_Interface * )
76 //------------------------------------------------------------------------------
77 static void SAL_CALL ExceptionThrower_dispatch(
78 uno_Interface * pUnoI, typelib_TypeDescription const * pMemberType,
79 void * pReturn, void * pArgs [], uno_Any ** ppException )
81 OSL_ASSERT( pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD );
83 switch (reinterpret_cast< typelib_InterfaceMemberTypeDescription * >(
84 const_cast< typelib_TypeDescription * >( pMemberType ) )->
85 nPosition)
87 case 0: // queryInterace()
89 Type const & rType_demanded =
90 *reinterpret_cast< Type const * >( pArgs[ 0 ] );
91 if (rType_demanded.equals(
92 ::getCppuType( reinterpret_cast<
93 Reference< XInterface > const * >(0) ) ) ||
94 rType_demanded.equals( ExceptionThrower::getCppuType() ))
96 typelib_TypeDescription * pTD = 0;
97 TYPELIB_DANGER_GET( &pTD, rType_demanded.getTypeLibType() );
98 uno_any_construct(
99 reinterpret_cast< uno_Any * >( pReturn ), &pUnoI, pTD, 0 );
100 TYPELIB_DANGER_RELEASE( pTD );
102 else
104 uno_any_construct(
105 reinterpret_cast< uno_Any * >( pReturn ), 0, 0, 0 );
107 *ppException = 0;
108 break;
110 case 1: // acquire()
111 case 2: // release()
112 *ppException = 0;
113 break;
114 case 3: // throwException()
116 uno_Any * pAny = reinterpret_cast< uno_Any * >( pArgs[ 0 ] );
117 OSL_ASSERT( pAny->pType->eTypeClass == typelib_TypeClass_EXCEPTION );
118 uno_type_any_construct( *ppException, pAny->pData, pAny->pType, 0 );
119 break;
121 default:
123 OSL_ASSERT( 0 );
124 RuntimeException exc(
125 "not implemented!", Reference< XInterface >() );
126 uno_type_any_construct(
127 *ppException, &exc, ::getCppuType( &exc ).getTypeLibType(), 0 );
128 break;
133 } // extern "C"
135 //______________________________________________________________________________
136 Any ExceptionThrower::queryInterface( Type const & type )
137 throw (RuntimeException)
139 if (type.equals( ::getCppuType( reinterpret_cast<
140 Reference< XInterface > const * >(0) ) ) ||
141 type.equals( ExceptionThrower::getCppuType() ))
143 XExceptionThrower * that = static_cast< XExceptionThrower * >( this );
144 return Any( &that, type );
146 return Any();
149 //______________________________________________________________________________
150 void ExceptionThrower::acquire() throw ()
153 //______________________________________________________________________________
154 void ExceptionThrower::release() throw ()
158 //______________________________________________________________________________
159 void ExceptionThrower::throwException( Any const & exc ) throw (Exception)
161 OSL_FAIL( "unexpected!" );
162 throwException( exc );
165 //______________________________________________________________________________
166 void ExceptionThrower::rethrowException() throw (Exception)
168 throw;
171 //______________________________________________________________________________
172 inline ExceptionThrower::ExceptionThrower()
174 uno_Interface::acquire = ExceptionThrower_acquire_release_nop;
175 uno_Interface::release = ExceptionThrower_acquire_release_nop;
176 uno_Interface::pDispatcher = ExceptionThrower_dispatch;
179 class theExceptionThrower : public rtl::Static<ExceptionThrower, theExceptionThrower> {};
181 } // anonymous namespace
184 namespace cppu
187 //==============================================================================
188 void SAL_CALL throwException( Any const & exc ) SAL_THROW( (Exception) )
190 if (exc.getValueTypeClass() != TypeClass_EXCEPTION)
192 throw RuntimeException(
193 "no UNO exception given "
194 "(must be derived from com::sun::star::uno::Exception)!",
195 Reference< XInterface >() );
198 Mapping uno2cpp(Environment(UNO_LB_UNO), Environment::getCurrent());
199 if (! uno2cpp.is())
201 throw RuntimeException(
202 "cannot get binary UNO to C++ mapping!",
203 Reference< XInterface >() );
206 Reference< XExceptionThrower > xThrower;
207 uno2cpp.mapInterface(
208 reinterpret_cast< void ** >( &xThrower ),
209 static_cast< uno_Interface * >( &theExceptionThrower::get() ),
210 ExceptionThrower::getCppuType() );
211 OSL_ASSERT( xThrower.is() );
212 xThrower->throwException( exc );
215 //==============================================================================
216 Any SAL_CALL getCaughtException()
218 Mapping cpp2uno(Environment::getCurrent(), Environment(UNO_LB_UNO));
219 if (! cpp2uno.is())
221 throw RuntimeException(
222 "cannot get C++ to binary UNO mapping!",
223 Reference< XInterface >() );
225 Mapping uno2cpp(Environment(UNO_LB_UNO), Environment::getCurrent());
226 if (! uno2cpp.is())
228 throw RuntimeException(
229 "cannot get binary UNO to C++ mapping!",
230 Reference< XInterface >() );
233 typelib_TypeDescription * pTD = 0;
234 TYPELIB_DANGER_GET(
235 &pTD, ExceptionThrower::getCppuType().getTypeLibType() );
237 UnoInterfaceReference unoI;
238 cpp2uno.mapInterface(
239 reinterpret_cast< void ** >( &unoI.m_pUnoI ),
240 static_cast< XExceptionThrower * >( &theExceptionThrower::get() ), pTD );
241 OSL_ASSERT( unoI.is() );
243 typelib_TypeDescription * pMemberTD = 0;
244 TYPELIB_DANGER_GET(
245 &pMemberTD,
246 reinterpret_cast< typelib_InterfaceTypeDescription * >( pTD )->
247 ppMembers[ 1 ] /* rethrowException() */ );
249 uno_Any exc_mem;
250 uno_Any * exc = &exc_mem;
251 unoI.dispatch( pMemberTD, 0, 0, &exc );
253 TYPELIB_DANGER_RELEASE( pMemberTD );
254 TYPELIB_DANGER_RELEASE( pTD );
256 if (exc == 0)
258 throw RuntimeException(
259 "rethrowing C++ exception failed!",
260 Reference< XInterface >() );
263 Any ret;
264 uno_any_destruct( &ret, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
265 uno_type_any_constructAndConvert(
266 &ret, exc->pData, exc->pType, uno2cpp.get() );
267 uno_any_destruct( exc, 0 );
268 return ret;
273 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */