1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: except.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_bridges.hxx"
40 #include <rtl/alloc.h>
41 #include <osl/diagnose.h>
43 #include <rtl/strbuf.hxx>
44 #include <typelib/typedescription.hxx>
45 #include <com/sun/star/uno/Any.hxx>
47 #include "bridges/cpp_uno/shared/arraypointer.hxx"
49 #include "cc50_solaris_intel.hxx"
53 // need a += operator for OString and sal_Char
56 inline OString
& operator+=( OString
& rString
, sal_Char cAdd
)
61 return rString
+= add
;
68 using namespace com::sun::star::uno
;
70 namespace CPPU_CURRENT_NAMESPACE
73 static OString
toUNOname( const OString
& rRTTIname
)
77 const sal_Char
* pRTTI
= rRTTIname
.getStr();
78 const sal_Char
* pOrg
= pRTTI
;
79 const sal_Char
* pLast
= pRTTI
;
83 if( *pRTTI
== ':' || ! *pRTTI
)
85 if( aRet
.getLength() )
87 aRet
+= rRTTIname
.copy( pLast
- pOrg
, pRTTI
- pLast
);
88 while( *pRTTI
== ':' )
100 //==================================================================================================
101 static OString
toRTTIname( const OString
& rUNOname
)
103 OStringBuffer
aRet( rUNOname
.getLength()*2 );
105 sal_Int32 nIndex
= 0;
110 aRet
.append( rUNOname
.getToken( 0, '.', nIndex
) );
111 } while( nIndex
!= -1 );
113 return aRet
.makeStringAndClear();
115 //==================================================================================================
117 static OString
toRTTImangledname( const OString
& rRTTIname
)
119 if( ! rRTTIname
.getLength() )
122 OStringBuffer
aRet( rRTTIname
.getLength()*2 );
124 aRet
.append( "__1n" );
125 sal_Int32 nIndex
= 0;
128 OString
aToken( rRTTIname
.getToken( 0, ':', nIndex
) );
129 int nBytes
= aToken
.getLength();
134 aRet
.append( (sal_Char
)( nBytes
/26 + 'a' ) );
135 aRet
.append( (sal_Char
)( nBytes
%26 + 'A' ) );
138 aRet
.append( (sal_Char
)( nBytes
+ 'A' ) );
139 for (sal_Int32 i
= 0; i
< aToken
.getLength(); ++i
) {
148 } while( nIndex
!= -1 );
152 return aRet
.makeStringAndClear();
155 //##################################################################################################
156 //#### RTTI simulation #############################################################################
157 //##################################################################################################
161 std::map
< OString
, void* > aAllRTTI
;
165 void* getRTTI( const OString
& rTypename
);
166 void* getRTTI_UnoName( const OString
& rUnoTypename
)
167 { return getRTTI( toRTTIname( rUnoTypename
) ); }
169 void* insertRTTI( const OString
& rTypename
);
170 void* insertRTTI_UnoName( const OString
& rTypename
)
171 { return insertRTTI( toRTTIname( rTypename
) ); }
172 void* generateRTTI( typelib_CompoundTypeDescription
* pCompTypeDescr
);
175 RTTIHolder::~RTTIHolder()
177 for ( std::map
< OString
, void* >::const_iterator
iPos( aAllRTTI
.begin() );
178 iPos
!= aAllRTTI
.end(); ++iPos
)
180 delete[] static_cast< char * >(iPos
->second
);
184 #if OSL_DEBUG_LEVEL > 1
188 void* RTTIHolder::getRTTI( const OString
& rTypename
)
190 std::map
< OString
, void* >::iterator element
;
192 element
= aAllRTTI
.find( rTypename
);
193 if( element
!= aAllRTTI
.end() )
194 return (*element
).second
;
196 // create rtti structure
197 element
= aAllRTTI
.find( rTypename
);
198 if( element
!= aAllRTTI
.end() )
199 return (*element
).second
;
204 static long nMagicId
= 1;
206 void* RTTIHolder::insertRTTI( const OString
& rTypename
)
208 OString
aMangledName( toRTTImangledname( rTypename
) );
209 NIST_Hash
aHash( aMangledName
.getStr(), aMangledName
.getLength() );
212 // rSuperTypename MUST exist !!!
213 std::size_t const RTTI_SIZE
= 19; // 14???
214 void** pRTTI
= reinterpret_cast< void ** >(
215 new char[RTTI_SIZE
* sizeof (void *) + strlen(rTypename
.getStr()) + 1]);
216 pRTTI
[ 0 ] = reinterpret_cast< void * >(RTTI_SIZE
* sizeof (void *));
218 pRTTI
[ 2 ] = (void*)(7*sizeof(void*));
219 pRTTI
[ 3 ] = (void*)aHash
.getHash()[0];
220 pRTTI
[ 4 ] = (void*)aHash
.getHash()[1];
221 pRTTI
[ 5 ] = (void*)aHash
.getHash()[2];
222 pRTTI
[ 6 ] = (void*)aHash
.getHash()[3];
226 pRTTI
[ 9 ] = pRTTI
[ 3 ];
227 pRTTI
[ 10 ] = pRTTI
[ 4 ];
228 pRTTI
[ 11 ] = pRTTI
[ 5 ];
229 pRTTI
[ 12 ] = pRTTI
[ 6 ];
230 pRTTI
[ 13 ] = (void*)0x80000000;
231 strcpy(reinterpret_cast< char * >(pRTTI
+ RTTI_SIZE
), rTypename
.getStr());
233 aAllRTTI
[ rTypename
] = (void*)pRTTI
;
234 #if OSL_DEBUG_LEVEL > 1
236 "generating base RTTI for type %s:\n"
238 " hash: %.8x %.8x %.8x %.8x\n",
240 aMangledName
.getStr(),
241 pRTTI
[ 3 ], pRTTI
[ 4 ], pRTTI
[ 5 ], pRTTI
[ 6 ]
247 void* RTTIHolder::generateRTTI( typelib_CompoundTypeDescription
* pCompTypeDescr
)
249 OString
aUNOCompTypeName( OUStringToOString( pCompTypeDescr
->aBase
.pTypeName
, RTL_TEXTENCODING_ASCII_US
) );
250 OString
aRTTICompTypeName( toRTTIname( aUNOCompTypeName
) );
252 void* pHaveRTTI
= getRTTI( aRTTICompTypeName
);
256 if( ! pCompTypeDescr
->pBaseTypeDescription
)
257 // this is a base type
258 return insertRTTI( aRTTICompTypeName
);
260 // get base class RTTI
261 void* pSuperRTTI
= generateRTTI( pCompTypeDescr
->pBaseTypeDescription
);
262 OSL_ENSURE( pSuperRTTI
, "could not generate RTTI for supertype !" );
264 // find out the size to allocate for RTTI
265 void** pInherit
= (void**)((sal_uInt32
)pSuperRTTI
+ ((sal_uInt32
*)pSuperRTTI
)[2] + 8);
267 for( nInherit
= 1; pInherit
[ nInherit
*5-1 ] != (void*)0x80000000; nInherit
++ )
270 OString
aMangledName( toRTTImangledname( aRTTICompTypeName
) );
271 NIST_Hash
aHash( aMangledName
.getStr(), aMangledName
.getLength() );
273 std::size_t const rttiSize
= 14 + nInherit
* 5;
274 void** pRTTI
= reinterpret_cast< void ** >(
276 rttiSize
* sizeof (void *)
277 + strlen(aRTTICompTypeName
.getStr()) + 1]);
278 pRTTI
[ 0 ] = reinterpret_cast< void * >(rttiSize
* sizeof (void *));
280 pRTTI
[ 2 ] = (void*)(7*sizeof(void*));
281 pRTTI
[ 3 ] = (void*)aHash
.getHash()[0];
282 pRTTI
[ 4 ] = (void*)aHash
.getHash()[1];
283 pRTTI
[ 5 ] = (void*)aHash
.getHash()[2];
284 pRTTI
[ 6 ] = (void*)aHash
.getHash()[3];
288 memcpy( pRTTI
+9, pInherit
, 4*nInherit
*5 );
289 pRTTI
[ 8 +nInherit
*5 ] = NULL
;
290 pRTTI
[ 9 +nInherit
*5 ] = pRTTI
[ 3 ];
291 pRTTI
[ 10+nInherit
*5 ] = pRTTI
[ 4 ];
292 pRTTI
[ 11+nInherit
*5 ] = pRTTI
[ 5 ];
293 pRTTI
[ 12+nInherit
*5 ] = pRTTI
[ 6 ];
294 pRTTI
[ 13+nInherit
*5 ] = (void*)0x80000000;
296 reinterpret_cast< char * >(pRTTI
+ rttiSize
),
297 aRTTICompTypeName
.getStr());
299 aAllRTTI
[ aRTTICompTypeName
] = (void*)pRTTI
;
301 #if OSL_DEBUG_LEVEL > 1
303 "generating struct RTTI for type %s:\n"
305 " hash: %.8x %.8x %.8X %.8x\n",
306 aRTTICompTypeName
.getStr(),
307 aMangledName
.getStr(),
308 pRTTI
[ 3 ], pRTTI
[ 4 ], pRTTI
[ 5 ], pRTTI
[ 6 ]
315 //__________________________________________________________________________________________________
317 static void deleteException(
318 void* pExc
, unsigned char* thunk
, typelib_TypeDescription
* pType
)
321 pExc
, pType
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
322 typelib_typedescription_release( pType
);
326 //__________________________________________________________________________________________________
328 //##################################################################################################
329 //#### exported ####################################################################################
330 //##################################################################################################
332 void cc50_solaris_intel_raiseException( uno_Any
* pUnoExc
, uno_Mapping
* pUno2Cpp
)
334 #if OSL_DEBUG_LEVEL > 1
337 *reinterpret_cast< OUString
const * >( &pUnoExc
->pType
->pTypeName
),
338 RTL_TEXTENCODING_ASCII_US
) );
339 fprintf( stderr
, "> uno exception occured: %s\n", cstr
.getStr() );
341 bridges::cpp_uno::shared::ArrayPointer
< unsigned char > thunkPtr(
342 new unsigned char[24]);
343 typelib_TypeDescription
* pTypeDescr
= 0;
344 // will be released by deleteException
345 typelib_typedescriptionreference_getDescription( &pTypeDescr
, pUnoExc
->pType
);
349 static ::osl::Mutex aMutex
;
350 ::osl::Guard
< ::osl::Mutex
> guard( aMutex
);
352 static RTTIHolder
* s_pRTTI
= 0;
355 #ifdef LEAK_STATIC_DATA
356 s_pRTTI
= new RTTIHolder();
358 static RTTIHolder s_aRTTI
;
363 pRTTI
= s_pRTTI
->generateRTTI( (typelib_CompoundTypeDescription
*)pTypeDescr
);
367 OSL_ENSURE( sizeof(sal_Int32
) == sizeof(void *), "### pointer size differs from sal_Int32!" );
369 void * pCppExc
= __Crun::ex_alloc( pTypeDescr
->nSize
);
370 uno_copyAndConvertData( pCppExc
, pUnoExc
->pData
, pTypeDescr
, pUno2Cpp
);
372 // destruct uno exception
373 uno_any_destruct( pUnoExc
, 0 );
375 unsigned char * thunk
= thunkPtr
.release();
381 *reinterpret_cast< void ** >(thunk
+ 3) = pTypeDescr
;
384 *reinterpret_cast< void ** >(thunk
+ 8) = thunk
;
389 // call deleteException:
392 void * d
= reinterpret_cast< void * >(deleteException
);
394 *reinterpret_cast< std::ptrdiff_t * >(thunk
+ 16) =
395 static_cast< unsigned char * >(d
) - (thunk
+ 20);
404 void (* f
)(void *) = reinterpret_cast< void (*)(void *) >(thunk
);
406 __Crun::ex_throw(pCppExc
, (const __Crun::static_type_info
*)pRTTI
, f
);
409 void cc50_solaris_intel_fillUnoException(
413 uno_Mapping
* pCpp2Uno
)
415 OSL_ASSERT( pInfo
!= 0 );
416 OString
uno_name( toUNOname( pInfo
) );
417 OUString
aName( OStringToOUString(
418 uno_name
, RTL_TEXTENCODING_ASCII_US
) );
419 typelib_TypeDescription
* pExcTypeDescr
= 0;
420 typelib_typedescription_getByName( &pExcTypeDescr
, aName
.pData
);
422 if (pExcTypeDescr
== 0) // the thing that should not be
424 RuntimeException
aRE(
425 OUString( RTL_CONSTASCII_USTRINGPARAM(
426 "exception type not found: ") ) + aName
,
427 Reference
< XInterface
>() );
428 Type
const & rType
= ::getCppuType( &aRE
);
429 uno_type_any_constructAndConvert(
430 pUnoExc
, &aRE
, rType
.getTypeLibType(), pCpp2Uno
);
431 #if OSL_DEBUG_LEVEL > 0
432 OString
cstr( OUStringToOString(
433 aRE
.Message
, RTL_TEXTENCODING_ASCII_US
) );
434 OSL_ENSURE( 0, cstr
.getStr() );
439 #if OSL_DEBUG_LEVEL > 1
440 fprintf( stderr
, "> c++ exception occured: %s\n",
441 ::rtl::OUStringToOString(
442 pExcTypeDescr
->pTypeName
,
443 RTL_TEXTENCODING_ASCII_US
).getStr() );
445 // construct uno exception any
446 uno_any_constructAndConvert(
447 pUnoExc
, pCppExc
, pExcTypeDescr
, pCpp2Uno
);
448 typelib_typedescription_release( pExcTypeDescr
);