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 ************************************************************************/
36 #include <rtl/alloc.h>
37 #include <rtl/instance.hxx>
38 #include <osl/diagnose.h>
40 #include <rtl/strbuf.hxx>
41 #include <typelib/typedescription.hxx>
42 #include <com/sun/star/uno/Any.hxx>
44 #include "bridges/cpp_uno/shared/arraypointer.hxx"
46 #include "cc50_solaris_intel.hxx"
50 // need a += operator for OString and sal_Char
51 using ::rtl::OUString
;
53 using ::rtl::OStringBuffer
;
54 using ::rtl::OUStringToOString
;
55 using ::rtl::OStringToOUString
;
57 inline OString
& operator+=( OString
& rString
, sal_Char cAdd
)
62 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 struct RTTISingleton
: public rtl::Static
< RTTIHolder
, RTTISingleton
> {};
317 //__________________________________________________________________________________________________
319 static void deleteException(
320 void* pExc
, unsigned char* thunk
, typelib_TypeDescription
* pType
)
323 pExc
, pType
, reinterpret_cast< uno_ReleaseFunc
>(cpp_release
) );
324 typelib_typedescription_release( pType
);
328 //__________________________________________________________________________________________________
330 //##################################################################################################
331 //#### exported ####################################################################################
332 //##################################################################################################
334 void cc50_solaris_intel_raiseException( uno_Any
* pUnoExc
, uno_Mapping
* pUno2Cpp
)
336 #if OSL_DEBUG_LEVEL > 1
339 *reinterpret_cast< OUString
const * >( &pUnoExc
->pType
->pTypeName
),
340 RTL_TEXTENCODING_ASCII_US
) );
341 fprintf( stderr
, "> uno exception occurred: %s\n", cstr
.getStr() );
343 bridges::cpp_uno::shared::ArrayPointer
< unsigned char > thunkPtr(
344 new unsigned char[24]);
345 typelib_TypeDescription
* pTypeDescr
= 0;
346 // will be released by deleteException
347 typelib_typedescriptionreference_getDescription( &pTypeDescr
, pUnoExc
->pType
);
349 void * pRTTI
= RTTISingleton::get().generateRTTI( (typelib_CompoundTypeDescription
*)pTypeDescr
);
352 OSL_ENSURE( sizeof(sal_Int32
) == sizeof(void *), "### pointer size differs from sal_Int32!" );
354 void * pCppExc
= __Crun::ex_alloc( pTypeDescr
->nSize
);
355 uno_copyAndConvertData( pCppExc
, pUnoExc
->pData
, pTypeDescr
, pUno2Cpp
);
357 // destruct uno exception
358 uno_any_destruct( pUnoExc
, 0 );
360 unsigned char * thunk
= thunkPtr
.release();
366 *reinterpret_cast< void ** >(thunk
+ 3) = pTypeDescr
;
369 *reinterpret_cast< void ** >(thunk
+ 8) = thunk
;
374 // call deleteException:
377 void * d
= reinterpret_cast< void * >(deleteException
);
379 *reinterpret_cast< std::ptrdiff_t * >(thunk
+ 16) =
380 static_cast< unsigned char * >(d
) - (thunk
+ 20);
389 void (* f
)(void *) = reinterpret_cast< void (*)(void *) >(thunk
);
391 __Crun::ex_throw(pCppExc
, (const __Crun::static_type_info
*)pRTTI
, f
);
394 void cc50_solaris_intel_fillUnoException(
398 uno_Mapping
* pCpp2Uno
)
400 OSL_ASSERT( pInfo
!= 0 );
401 OString
uno_name( toUNOname( pInfo
) );
402 OUString
aName( OStringToOUString(
403 uno_name
, RTL_TEXTENCODING_ASCII_US
) );
404 typelib_TypeDescription
* pExcTypeDescr
= 0;
405 typelib_typedescription_getByName( &pExcTypeDescr
, aName
.pData
);
407 if (pExcTypeDescr
== 0) // the thing that should not be
409 RuntimeException
aRE(
410 OUString( RTL_CONSTASCII_USTRINGPARAM(
411 "exception type not found: ") ) + aName
,
412 Reference
< XInterface
>() );
413 Type
const & rType
= ::getCppuType( &aRE
);
414 uno_type_any_constructAndConvert(
415 pUnoExc
, &aRE
, rType
.getTypeLibType(), pCpp2Uno
);
416 #if OSL_DEBUG_LEVEL > 0
417 OString
cstr( OUStringToOString(
418 aRE
.Message
, RTL_TEXTENCODING_ASCII_US
) );
419 OSL_FAIL( cstr
.getStr() );
424 #if OSL_DEBUG_LEVEL > 1
425 fprintf( stderr
, "> c++ exception occurred: %s\n",
426 ::rtl::OUStringToOString(
427 pExcTypeDescr
->pTypeName
,
428 RTL_TEXTENCODING_ASCII_US
).getStr() );
430 // construct uno exception any
431 uno_any_constructAndConvert(
432 pUnoExc
, pCppExc
, pExcTypeDescr
, pCpp2Uno
);
433 typelib_typedescription_release( pExcTypeDescr
);
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */