$NetBSD: patch-ad,v 1.1.1.1 2002/02/13 18:09:23 mrauch Exp $

--- ../bridges/source/cpp_uno/gcc2_netbsd_intel/except.cxx.orig	Sun Jan  6 11:41:58 2002
+++ ../bridges/source/cpp_uno/gcc2_netbsd_intel/except.cxx
@@ -0,0 +1,305 @@
+#include <dlfcn.h>
+#include <new.h>
+#include <typeinfo>
+#if STLPORT_VERSION<321
+#include <map.h>
+#else
+#include <map>
+#endif
+#ifndef _RTL_ALLOC_H_
+#include <rtl/alloc.h>
+#endif
+#ifndef _OSL_DIAGNOSE_H_
+#include <osl/diagnose.h>
+#endif
+
+#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_
+#include <bridges/cpp_uno/bridge.hxx>
+#endif
+#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_
+#include <typelib/typedescription.hxx>
+#endif
+#ifndef _COM_SUN_STAR_UNO_ANY_HXX_
+#include <com/sun/star/uno/Any.hxx>
+#endif
+
+#include <rtl/strbuf.hxx>
+
+#include "gcc2_netbsd_intel.hxx"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+using namespace std;
+using namespace osl;
+using namespace rtl;
+using namespace com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+	
+//==================================================================================================
+static OString toUNOname( const OString & rRTTIname )
+{
+	OString aRet;
+	
+	sal_Char* pStr = rRTTIname.getStr();
+	sal_Char* pOrg = pStr;
+
+	// check for namespace
+	if( *pStr == '_' )
+		pStr++;
+	if( *pStr == 'Q' )
+	{
+		pStr++;
+		if( *pStr++ == '_' )
+		{
+			while( *pStr++ != '_' )
+				;
+		}
+	}
+
+	while( *pStr )
+	{
+		int nCharsToCopy = 0;
+		while( *pStr >= '0' && *pStr <= '9' )
+			nCharsToCopy = 10*nCharsToCopy + (int)(*pStr++ - '0');
+		if( aRet.getLength() )
+			aRet += ".";
+		aRet += rRTTIname.copy( pStr - pOrg, nCharsToCopy );
+		pStr += nCharsToCopy;
+	}
+	
+	return aRet;
+}
+//==================================================================================================
+static OString toRTTIname( const OString & rUNOname )
+{
+	if( ! rUNOname.getLength() )
+		return OString();
+    
+	OStringBuffer aRet( 64 );
+    
+    sal_Int32 nIndex = 0;
+    sal_Int32 nToken = 0;
+	do
+    {
+		OString aToken( rUNOname.getToken( 0, '.', nIndex ) );
+        aRet.append( OString::valueOf( (sal_Int32)aToken.getLength() ) );
+		aRet.append( aToken );
+        ++nToken;
+	}
+    while (nIndex >= 0);
+
+    OString ret( aRet.makeStringAndClear() );
+    
+	if( nToken >= 2 )
+	{
+        OStringBuffer buf( 64 );
+		buf.append( 'Q' );
+		if( nToken > 9 )
+            aRet.append( '_' );
+        buf.append( OString::valueOf( (sal_Int32)nToken ) );
+		if( nToken > 9 )
+            aRet.append( '_' );
+        buf.append( ret );
+        ret = buf.makeStringAndClear();
+	}
+    
+    return ret;
+}
+
+ 
+//##################################################################################################
+//#### RTTI simulation #############################################################################
+//##################################################################################################
+
+class RTTIHolder
+{
+	static std::map< OString, void* > aAllRTTI;
+public:
+	static void* getRTTI( const OString& rTypename );
+	static void* getRTTI_UnoName( const OString& rUnoTypename )
+		{ return getRTTI( toRTTIname( rUnoTypename ) ); }
+
+	static void* insertRTTI( const OString& rTypename );
+	static void* insertRTTI_UnoName( const OString& rTypename )
+		{ return insertRTTI( toRTTIname( rTypename ) ); }
+
+	// rSuperTypename MUST exist !!!
+	static void* insertRTTI( const OString& rTypename, const OString& rSuperTypename );
+	static void* insertRTTI_UnoNames( const OString& rTypename, const OString& rSuperTypename )
+		{ return insertRTTI( toRTTIname( rTypename ), toRTTIname( rSuperTypename ) ); }
+
+	// for complex RTTI
+	static void* insertRTTI( const OString& rTypename, void* pRTTI );
+	static void* insertRTTI_UnoName( const OString&rTypename, void* pRTTI )
+		{ return insertRTTI( toRTTIname( rTypename ), pRTTI ); }
+};
+
+std::map< OString, void* > RTTIHolder::aAllRTTI;
+
+void* RTTIHolder::getRTTI( const OString& rTypename )
+{
+	std::map< OString, void* >::iterator element;
+
+	element = aAllRTTI.find( rTypename );
+	return element != aAllRTTI.end() ? (*element).second : NULL;
+}
+
+void* RTTIHolder::insertRTTI( const OString& rTypename )
+{
+#ifdef DEBUG
+	fprintf( stderr, "generating  base RTTI: %s\n", rTypename.getStr() );
+#endif
+	void* pRTTI = new __user_type_info( strdup( rTypename.getStr() ) );
+	aAllRTTI[ rTypename ] = pRTTI;
+	return pRTTI;
+}
+
+void* RTTIHolder::insertRTTI( const OString& rTypename, const OString& rSuperTypename )
+{
+#ifdef DEBUG
+	fprintf( stderr, "generating subclass RTTI: %s %s\n", rTypename.getStr(), rSuperTypename.getStr() );
+#endif
+	OSL_ENSURE( ! getRTTI( rTypename ), "insert RTTI called on already existing type" );
+	void* pRTTI = new __si_type_info( strdup( rTypename.getStr() ), *(__user_type_info*)getRTTI( rSuperTypename ) );
+	aAllRTTI[ rTypename ] = pRTTI;
+	return pRTTI;
+}
+
+void* RTTIHolder::insertRTTI( const OString& rTypename, void* pRTTI )
+{
+	aAllRTTI[ rTypename ] = pRTTI;
+	return pRTTI;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static void* generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr )
+{
+	OString aCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+	void* pRTTI = RTTIHolder::getRTTI_UnoName( aCompTypeName );
+	if( pRTTI )
+		return pRTTI;
+	
+	if( ! pCompTypeDescr->pBaseTypeDescription )
+		// this is a base type
+		return RTTIHolder::insertRTTI_UnoName( aCompTypeName );
+	if( ! pCompTypeDescr->pBaseTypeDescription->pBaseTypeDescription )
+	{
+		OString aBasename(
+						  OUStringToOString( pCompTypeDescr->pBaseTypeDescription->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US )
+		);
+		if( ! RTTIHolder::getRTTI_UnoName( aBasename ) )
+			RTTIHolder::insertRTTI_UnoName( aBasename );
+
+		// this type has only one supertype
+		return RTTIHolder::insertRTTI_UnoNames( aCompTypeName, aBasename );
+	}
+	
+	// create __si_type_info
+	void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription );
+	OString aCompTypeRTTIname( toRTTIname( aCompTypeName ) );
+#ifdef DEBUG
+	fprintf( stderr, "generating RTTI: %s\n", aCompTypeRTTIname.getStr() );
+#endif
+	pRTTI = new __si_type_info( strdup( aCompTypeRTTIname.getStr() ),
+								*(__user_type_info*)pSuperRTTI );
+#if 0
+	__class_type_info::base_info* pBaseInfo = new __class_type_info::base_info;
+	pBaseInfo->base = (__user_type_info*)pSuperRTTI;
+	pBaseInfo->offset = 0;
+	pBaseInfo->is_virtual = 0;
+	pBaseInfo->access1 = __class_type_info::PUBLIC;
+
+	OString aCompTypeRTTIname( toRTTIname( aCompTypeName ) );
+	pRTTI = new __class_type_info(
+		strdup( aCompTypeRTTIname.getStr() ),
+		pBaseInfo,
+		1
+		);
+#endif
+	return RTTIHolder::insertRTTI_UnoName( aCompTypeName, pRTTI );
+}
+
+//--------------------------------------------------------------------------------------------------
+
+static Mutex s_aMutex;
+static std::map< void*, typelib_TypeDescription* > aExceptionMap;
+
+static void deleteException( void* pExc, int nDummy )
+{
+	MutexGuard aGuard( s_aMutex );
+	std::map< void*, typelib_TypeDescription* >::iterator element =
+		aExceptionMap.find( pExc );
+	OSL_ASSERT( element != aExceptionMap.end() );
+	if( element != aExceptionMap.end() )
+	{
+		typelib_TypeDescription* pType = (*element).second;
+		aExceptionMap.erase( pExc );
+		uno_destructData( pExc, pType, cpp_release );
+		typelib_typedescription_release( pType );
+	}
+}
+
+//__________________________________________________________________________________________________
+
+//##################################################################################################
+//#### exported ####################################################################################
+//##################################################################################################
+
+
+void gcc291_netbsd_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
+{
+	// construct cpp exception object
+	typelib_TypeDescription * pTypeDescr = 0;
+	typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType );
+	
+	void * pCppExc = __eh_alloc( pTypeDescr->nSize ); // will be released in generated dtor
+	uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
+	
+	// destruct uno exception
+	uno_any_destruct( pUnoExc, 0 );
+	
+	// a must be
+	OSL_ENSURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" );
+
+	typelib_CompoundTypeDescription * pCompTypeDescr = (typelib_CompoundTypeDescription *)pTypeDescr;
+	void* pRTTI = generateRTTI( pCompTypeDescr );
+
+	{
+	MutexGuard aGuard( s_aMutex );
+	aExceptionMap[ pCppExc ] = pTypeDescr;
+	}
+	
+	__cp_push_exception( pCppExc, pRTTI, deleteException );
+	__throw();
+}
+
+void gcc291_netbsd_intel_fillUnoException( cp_eh_info* pInfo, uno_Any* pExc, uno_Mapping * pCpp2Uno )
+{
+	OUString aName( OStringToOUString(
+		toUNOname( ((__user_type_info*)(pInfo->type))->name() ), RTL_TEXTENCODING_ASCII_US ) );
+	
+	typelib_TypeDescription * pExcTypeDescr = 0;
+	typelib_typedescription_getByName(
+		&pExcTypeDescr,
+		aName.pData );
+	OSL_ENSURE( pExcTypeDescr, "could not get type description for exception" );
+	if (pExcTypeDescr)
+	{
+		// construct cpp exception any
+		Any aAny( pInfo->value, pExcTypeDescr ); // const_cast
+		typelib_typedescription_release( pExcTypeDescr );
+		// construct uno exception any
+		typelib_TypeDescription* pAnyDescr = 0;
+		getCppuType( (const Any *)0 ).getDescription( &pAnyDescr );
+		uno_copyAndConvertData( pExc, &aAny, pAnyDescr, pCpp2Uno );
+		typelib_typedescription_release( pAnyDescr );
+	}
+}
+
+}
+
