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
;
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()
65 reinterpret_cast< Reference
< XExceptionThrower
> const * >(0) );
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 ();
75 virtual void SAL_CALL
throwException( Any
const & exc
) throw (Exception
);
76 virtual void SAL_CALL
rethrowException() throw (Exception
);
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
) )->
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() );
110 reinterpret_cast< uno_Any
* >( pReturn
), &pUnoI
, pTD
, 0 );
111 TYPELIB_DANGER_RELEASE( pTD
);
116 reinterpret_cast< uno_Any
* >( pReturn
), 0, 0, 0 );
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 );
135 RuntimeException
exc(
136 OUSTR("not implemented!"), Reference
< XInterface
>() );
137 uno_type_any_construct(
138 *ppException
, &exc
, ::getCppuType( &exc
).getTypeLibType(), 0 );
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
);
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
)
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
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());
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
)));
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());
239 throw RuntimeException(
240 OUSTR("cannot get binary UNO to C++ mapping!"),
241 Reference
< XInterface
>() );
244 typelib_TypeDescription
* pTD
= 0;
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;
257 reinterpret_cast< typelib_InterfaceTypeDescription
* >( pTD
)->
258 ppMembers
[ 1 ] /* rethrowException() */ );
261 uno_Any
* exc
= &exc_mem
;
262 unoI
.dispatch( pMemberTD
, 0, 0, &exc
);
264 TYPELIB_DANGER_RELEASE( pMemberTD
);
265 TYPELIB_DANGER_RELEASE( pTD
);
269 throw RuntimeException(
270 OUSTR("rethrowing C++ exception failed!"),
271 Reference
< XInterface
>() );
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 );
284 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */