summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2003-07-16 16:33:00 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2003-07-16 16:33:00 +0000
commit5c18d77608e6700064e87067509d17dc91aa6f0e (patch)
tree40de8839a3bdfd8147468069618eab9a32e4499b /bridges
parent80288501169009ef9e4e80a9204f084d8d6c5987 (diff)
INTEGRATION: CWS ooo11rc2 (1.1.4); FILE ADDED
2003/07/14 15:35:37 fa 1.1.4.1: Add gcc3 C++ <-> UNO bridge code for OS X and conditionalize the old gcc 2 bridge code for gcc 2.95 only. http://www.openoffice.org/project/www/issues/show_bug.cgi?id=16616 Contributors: Kevin Hendricks Dan Williams Dan fa@ooo
Diffstat (limited to 'bridges')
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx120
-rw-r--r--bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx652
2 files changed, 772 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx
new file mode 100644
index 000000000000..a662b7205d67
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/share.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * $RCSfile: share.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: hr $ $Date: 2003-07-16 17:32:51 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx
new file mode 100644
index 000000000000..417cd5d2b1fc
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_macosx_powerpc/uno2cpp.cxx
@@ -0,0 +1,652 @@
+/*************************************************************************
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: hr $ $Date: 2003-07-16 17:33:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <sys/types.h>
+#include <sys/malloc.h>
+#include <rtl/alloc.h>
+
+#include <uno/data.h>
+#include <bridges/cpp_uno/bridge.hxx>
+#include <bridges/cpp_uno/type_misc.hxx>
+
+#include "share.hxx"
+
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+//==================================================================================================
+static void callVirtualMethod(
+ void * pThis,
+ sal_Int32 nVtableIndex,
+ void * pRegisterReturn,
+ typelib_TypeClass eReturnType,
+ char * pPT,
+ sal_Int32 * pStackLongs,
+ sal_Int32 nStackLongs)
+{
+
+ // parameter list is mixed list of * and values
+ // reference parameters are pointers
+
+ // the basic idea here is to use gpr[8] as a storage area for
+ // the future values of registers r3 to r10 needed for the call,
+ // and similarly fpr[13] as a storage area for the future values
+ // of floating point registers f1 to f13
+
+ unsigned long * mfunc; // actual function to be invoked
+ void (*ptr)();
+ int gpr[8]; // storage for gpregisters, map to r3-r10
+ int off; // offset used to find function
+ double fpr[13]; // storage for fpregisters, map to f1-f13
+ int n; // number of gprs mapped so far
+ int f; // number of fprs mapped so far
+ volatile long *p; // pointer to parameter overflow area
+ int c; // character of parameter type being decoded
+ volatile double dret; // temporary function return values
+ volatile int iret, iret2;
+
+ // Because of the Power PC calling conventions we could be passing
+ // parameters in both register types and on the stack. To create the
+ // stack parameter area we need we now simply allocate local
+ // variable storage param[] that is at least the size of the parameter stack
+ // (more than enough space) which we can overwrite the parameters into.
+
+ // Note: This keeps us from having to decode the signature twice and
+ // prevents problems with later local variables.
+
+ // FIXME: I do not believe the following is true but we will keep the
+ // FIXME: extra space just to be safe until proven otherwise
+
+ // Note: could require up to 2*nStackLongs words of parameter stack area
+ // if the call has many float parameters (i.e. floats take up only 1
+ // word on the stack but take 2 words in parameter area in the
+ // stack frame .
+
+
+ unsigned long param[(2*nStackLongs)];
+
+ /* now begin to load the C++ function arguments into storage */
+ n = 0;
+ f = 0;
+
+
+ /* set up a pointer to the stack parameter area */
+ __asm__ ( "addi %0,r1,24" : "=r" (p) : /* no inputs */ );
+
+
+ // FIXME: why is this here at all?
+ // never called
+ // if (! pThis) dummy_can_throw_anything("xxx"); // address something
+
+
+ // now we need to parse the entire signature string
+ // until we get the END indicator
+
+ // treat complex return pointer like any other parameter
+
+ // parse the argument list up to the ending )
+
+ while (*pPT != 'X') {
+ c = *pPT;
+ switch (c) {
+
+ case 'D': /* type is double */
+ if (f < 13) {
+ fpr[f++] = *((double *)pStackLongs); /* store in register */
+ n+=2;
+ p+=2;
+ } else {
+ *p++ = *pStackLongs; /* or on the parameter stack */
+ *p++ = *(pStackLongs + 1);
+ }
+ pStackLongs += 2;
+ break;
+
+ case 'F': /* type is float */
+ /* floats are stored as 1 32 bit word on param stack */
+ if (f < 13) {
+ fpr[f++] = *((float *)pStackLongs);
+ n+=1;
+ p++;
+ } else {
+ *((float *)p) = *((float *)pStackLongs);
+ p += 1;
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'H': /* type is long long */
+ if (n < 8)
+ {
+ gpr[n++] = *pStackLongs;
+ p++;
+ }
+ else
+ *p++ = *pStackLongs;
+ if(n < 8)
+ {
+ gpr[n++] = *(pStackLongs+1);
+ p++;
+ }
+ else
+ *p++ = *(pStackLongs+1);
+ pStackLongs += 2;
+ break;
+
+ case 'S':
+ if (n < 8) {
+ gpr[n++] = *((unsigned short*)pStackLongs);
+ p++;
+ } else {
+ *p++ = *((unsigned short *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ case 'B':
+ if (n < 8) {
+ gpr[n++] = *((char *)pStackLongs);
+ p++;
+ } else {
+ *p++ = *((char *)pStackLongs);
+ }
+ pStackLongs += 1;
+ break;
+
+ default:
+ if (n < 8) {
+ gpr[n++] = *pStackLongs;
+ p++;
+ } else {
+ *p++ = *pStackLongs;
+ }
+ pStackLongs += 1;
+ break;
+ }
+ pPT++;
+ }
+
+
+ /* figure out the address of the function we need to invoke */
+ off = nVtableIndex;
+ off = off * 4; // 4 bytes per slot
+ mfunc = *((unsigned long **)pThis); // get the address of the vtable
+ mfunc = (unsigned long *)((char *)mfunc + off); // get the address from the vtable entry at offset
+ mfunc = *((unsigned long **)mfunc); // the function is stored at the address
+ ptr = (void (*)())mfunc;
+
+ /* Set up the machine registers and invoke the function */
+
+ __asm__ __volatile__ (
+ "lwz r3, 0(%0)\n\t"
+ "lwz r4, 4(%0)\n\t"
+ "lwz r5, 8(%0)\n\t"
+ "lwz r6, 12(%0)\n\t"
+ "lwz r7, 16(%0)\n\t"
+ "lwz r8, 20(%0)\n\t"
+ "lwz r9, 24(%0)\n\t"
+ "lwz r10, 28(%0)\n\t"
+ "lfd f1, 0(%1)\n\t"
+ "lfd f2, 8(%1)\n\t"
+ "lfd f3, 16(%1)\n\t"
+ "lfd f4, 24(%1)\n\t"
+ "lfd f5, 32(%1)\n\t"
+ "lfd f6, 40(%1)\n\t"
+ "lfd f7, 48(%1)\n\t"
+ "lfd f8, 56(%1)\n\t"
+ "lfd f9, 64(%1)\n\t"
+ "lfd f10, 72(%1)\n\t"
+ "lfd f11, 80(%1)\n\t"
+ "lfd f12, 88(%1)\n\t"
+ "lfd f13, 96(%1)\n\t"
+ : : "r" (gpr), "r" (fpr)
+ : "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
+ "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9",
+ "f10", "f11", "f12", "f13"
+ );
+
+ (*ptr)();
+
+
+ __asm__ __volatile__ (
+ "stw r3, %1\n\t"
+ "stw r4, %2\n\t"
+ "stfd f1, %0\n\t"
+ : : "m" (dret), "m" (iret), "m" (iret2)
+ );
+
+
+ switch( eReturnType )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ ((long*)pRegisterReturn)[1] = iret2;
+ // fall thru on purpose
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ ((long*)pRegisterReturn)[0] = iret;
+ break;
+
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *(unsigned short*)pRegisterReturn = (unsigned short)iret;
+ break;
+
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *(unsigned char*)pRegisterReturn = (unsigned char)iret;
+ break;
+
+ case typelib_TypeClass_FLOAT:
+ *(float*)pRegisterReturn = (float)dret;
+ break;
+
+ case typelib_TypeClass_DOUBLE:
+ *(double*)pRegisterReturn = dret;
+ break;
+ }
+}
+
+
+//==================================================================================================
+static void cpp_call(
+ cppu_unoInterfaceProxy * pThis,
+ sal_Int32 nVtableCall,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: [complex ret ptr], values|ptr ...
+ char * pCppStack =
+ (char *)alloca( sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
+ char * pCppStackStart = pCppStack;
+
+ // need to know parameter types for callVirtualMethod so generate a signature string
+ char * pParamType = (char *) alloca(nParams+2);
+ char * pPT = pParamType;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (cppu_isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (cppu_relatesToInterface( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ *pPT++ = 'C'; //signify that a complex return type on stack
+ pCppStack += sizeof(void *);
+ }
+ }
+ // push this
+ *(void**)pCppStack = pThis->pCppI;
+ pCppStack += sizeof( void* );
+ *pPT++ = 'I';
+
+ // stack space
+ OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
+ // args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && cppu_isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ &pThis->pBridge->aUno2Cpp );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ // we need to know type of each param so that we know whether to use
+ // gpr or fpr to pass in parameters:
+ // Key: I - int, long, pointer, etc means pass in gpr
+ // B - byte value passed in gpr
+ // S - short value passed in gpr
+ // F - float value pass in fpr
+ // D - double value pass in fpr
+ // H - long long int pass in proper pairs of gpr (3,4) (5,6), etc
+ // X - indicates end of parameter description string
+
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pPT++ = 'I';
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pPT++ = 'S';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pPT++ = 'B';
+ break;
+ case typelib_TypeClass_FLOAT:
+ *pPT++ = 'F';
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *pPT++ = 'D';
+ pCppStack += sizeof(sal_Int32); // extra long
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pPT++ = 'H';
+ pCppStack += sizeof(sal_Int32); // extra long
+ }
+
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (cppu_relatesToInterface( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, &pThis->pBridge->aUno2Cpp );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ *pPT++='I';
+ }
+ pCppStack += sizeof(sal_Int32); // standard parameter length
+ }
+
+ // terminate the signature string
+ *pPT++='X';
+ *pPT=0;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pThis->pCppI, nVtableCall,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( __cxa_get_globals()->caughtExceptions, *ppUnoExc, &pThis->pBridge->aCpp2Uno );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+
+//==================================================================================================
+void SAL_CALL cppu_unoInterfaceProxy_dispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException ) throw ()
+{
+ // is my surrogate
+ cppu_unoInterfaceProxy * pThis = (cppu_unoInterfaceProxy *)pUnoI;
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall +1, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ switch (nVtableCall)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->pBridge->pUnoEnv->getRegisteredInterface)(
+ pThis->pBridge->pUnoEnv,
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+}
+