Version 3.6.0.2, tag libreoffice-3.6.0.2
[LibreOffice.git] / cppuhelper / source / exc_thrower.cxx
blob37cccf99525fb33e25dec0244662f52261f6dfec
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
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.
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).
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.
27 ************************************************************************/
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"
39 #include "cppuhelper/exc_hlp.hxx"
41 #define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
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;
50 namespace
53 using cppuhelper::detail::XExceptionThrower;
55 //==============================================================================
56 struct ExceptionThrower : public uno_Interface, XExceptionThrower
58 inline ExceptionThrower();
60 virtual ~ExceptionThrower() {}
62 static inline Type const & getCppuType()
64 return ::getCppuType(
65 reinterpret_cast< Reference< XExceptionThrower > const * >(0) );
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 ();
74 // XExceptionThrower
75 virtual void SAL_CALL throwException( Any const & exc ) throw (Exception);
76 virtual void SAL_CALL rethrowException() throw (Exception);
79 extern "C"
82 //------------------------------------------------------------------------------
83 static void SAL_CALL ExceptionThrower_acquire_release_nop(
84 SAL_UNUSED_PARAMETER uno_Interface * )
87 //------------------------------------------------------------------------------
88 static void SAL_CALL ExceptionThrower_dispatch(
89 uno_Interface * pUnoI, typelib_TypeDescription const * pMemberType,
90 void * pReturn, void * pArgs [], uno_Any ** ppException )
92 OSL_ASSERT( pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD );
94 switch (reinterpret_cast< typelib_InterfaceMemberTypeDescription * >(
95 const_cast< typelib_TypeDescription * >( pMemberType ) )->
96 nPosition)
98 case 0: // queryInterace()
100 Type const & rType_demanded =
101 *reinterpret_cast< Type const * >( pArgs[ 0 ] );
102 if (rType_demanded.equals(
103 ::getCppuType( reinterpret_cast<
104 Reference< XInterface > const * >(0) ) ) ||
105 rType_demanded.equals( ExceptionThrower::getCppuType() ))
107 typelib_TypeDescription * pTD = 0;
108 TYPELIB_DANGER_GET( &pTD, rType_demanded.getTypeLibType() );
109 uno_any_construct(
110 reinterpret_cast< uno_Any * >( pReturn ), &pUnoI, pTD, 0 );
111 TYPELIB_DANGER_RELEASE( pTD );
113 else
115 uno_any_construct(
116 reinterpret_cast< uno_Any * >( pReturn ), 0, 0, 0 );
118 *ppException = 0;
119 break;
121 case 1: // acquire()
122 case 2: // release()
123 *ppException = 0;
124 break;
125 case 3: // throwException()
127 uno_Any * pAny = reinterpret_cast< uno_Any * >( pArgs[ 0 ] );
128 OSL_ASSERT( pAny->pType->eTypeClass == typelib_TypeClass_EXCEPTION );
129 uno_type_any_construct( *ppException, pAny->pData, pAny->pType, 0 );
130 break;
132 default:
134 OSL_ASSERT( 0 );
135 RuntimeException exc(
136 OUSTR("not implemented!"), Reference< XInterface >() );
137 uno_type_any_construct(
138 *ppException, &exc, ::getCppuType( &exc ).getTypeLibType(), 0 );
139 break;
144 } // extern "C"
146 //______________________________________________________________________________
147 Any ExceptionThrower::queryInterface( Type const & type )
148 throw (RuntimeException)
150 if (type.equals( ::getCppuType( reinterpret_cast<
151 Reference< XInterface > const * >(0) ) ) ||
152 type.equals( ExceptionThrower::getCppuType() ))
154 XExceptionThrower * that = static_cast< XExceptionThrower * >( this );
155 return Any( &that, type );
157 return Any();
160 //______________________________________________________________________________
161 void ExceptionThrower::acquire() throw ()
164 //______________________________________________________________________________
165 void ExceptionThrower::release() throw ()
169 //______________________________________________________________________________
170 void ExceptionThrower::throwException( Any const & exc ) throw (Exception)
172 OSL_FAIL( "unexpected!" );
173 throwException( exc );
176 //______________________________________________________________________________
177 void ExceptionThrower::rethrowException() throw (Exception)
179 throw;
182 //______________________________________________________________________________
183 inline ExceptionThrower::ExceptionThrower()
185 uno_Interface::acquire = ExceptionThrower_acquire_release_nop;
186 uno_Interface::release = ExceptionThrower_acquire_release_nop;
187 uno_Interface::pDispatcher = ExceptionThrower_dispatch;
190 class theExceptionThrower : public rtl::Static<ExceptionThrower, theExceptionThrower> {};
192 } // anonymous namespace
195 namespace cppu
198 //==============================================================================
199 void SAL_CALL throwException( Any const & exc ) SAL_THROW( (Exception) )
201 if (exc.getValueTypeClass() != TypeClass_EXCEPTION)
203 throw RuntimeException(
204 OUSTR("no UNO exception given "
205 "(must be derived from com::sun::star::uno::Exception)!"),
206 Reference< XInterface >() );
209 Mapping uno2cpp(Environment(OUSTR(UNO_LB_UNO)), Environment::getCurrent());
210 if (! uno2cpp.is())
212 throw RuntimeException(
213 OUSTR("cannot get binary UNO to C++ mapping!"),
214 Reference< XInterface >() );
217 Reference< XExceptionThrower > xThrower;
218 uno2cpp.mapInterface(
219 reinterpret_cast< void ** >( &xThrower ),
220 static_cast< uno_Interface * >( &theExceptionThrower::get() ),
221 ExceptionThrower::getCppuType() );
222 OSL_ASSERT( xThrower.is() );
223 xThrower->throwException( exc );
226 //==============================================================================
227 Any SAL_CALL getCaughtException()
229 Mapping cpp2uno(Environment::getCurrent(), Environment(OUSTR(UNO_LB_UNO)));
230 if (! cpp2uno.is())
232 throw RuntimeException(
233 OUSTR("cannot get C++ to binary UNO mapping!"),
234 Reference< XInterface >() );
236 Mapping uno2cpp(Environment(OUSTR(UNO_LB_UNO)), Environment::getCurrent());
237 if (! uno2cpp.is())
239 throw RuntimeException(
240 OUSTR("cannot get binary UNO to C++ mapping!"),
241 Reference< XInterface >() );
244 typelib_TypeDescription * pTD = 0;
245 TYPELIB_DANGER_GET(
246 &pTD, ExceptionThrower::getCppuType().getTypeLibType() );
248 UnoInterfaceReference unoI;
249 cpp2uno.mapInterface(
250 reinterpret_cast< void ** >( &unoI.m_pUnoI ),
251 static_cast< XExceptionThrower * >( &theExceptionThrower::get() ), pTD );
252 OSL_ASSERT( unoI.is() );
254 typelib_TypeDescription * pMemberTD = 0;
255 TYPELIB_DANGER_GET(
256 &pMemberTD,
257 reinterpret_cast< typelib_InterfaceTypeDescription * >( pTD )->
258 ppMembers[ 1 ] /* rethrowException() */ );
260 uno_Any exc_mem;
261 uno_Any * exc = &exc_mem;
262 unoI.dispatch( pMemberTD, 0, 0, &exc );
264 TYPELIB_DANGER_RELEASE( pMemberTD );
265 TYPELIB_DANGER_RELEASE( pTD );
267 if (exc == 0)
269 throw RuntimeException(
270 OUSTR("rethrowing C++ exception failed!"),
271 Reference< XInterface >() );
274 Any ret;
275 uno_any_destruct( &ret, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
276 uno_type_any_constructAndConvert(
277 &ret, exc->pData, exc->pType, uno2cpp.get() );
278 uno_any_destruct( exc, 0 );
279 return ret;
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */