diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2003-03-18 18:07:19 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2003-03-18 18:07:19 +0000 |
commit | 4afcc7135e0bef66e7a218141bc93a6aa6128fd8 (patch) | |
tree | 3916ee844f4c22fa43650413f3023ab4cbf9e178 | |
parent | d26ec88993159d1cad127c1354a1ebfb8d1110cc (diff) |
MWS_SRX644: migrate branch mws_srx644 -> HEAD
48 files changed, 8414 insertions, 930 deletions
diff --git a/bridges/prj/build.lst b/bridges/prj/build.lst index ade4ceb8127b..c8a607b9d344 100644 --- a/bridges/prj/build.lst +++ b/bridges/prj/build.lst @@ -1,4 +1,4 @@ -br bridges : cppuhelper jurt NULL +br bridges : cppuhelper jurt jvmaccess NULL br bridges usr1 - all br_mkout NULL br bridges\unotypes nmake - all br_unotypes NULL br bridges\source\remote\static nmake - all br_rem_static br_unotypes NULL @@ -9,8 +9,11 @@ br bridges\source\cpp_uno\msvc_win32_intel nmake - w br_msci br_unotypes NULL br bridges\source\cpp_uno\gcc2_linux_intel nmake - u br_gccli br_unotypes NULL br bridges\source\cpp_uno\gcc3_linux_intel nmake - u br_gcc3li br_unotypes NULL br bridges\source\cpp_uno\gcc2_freebsd_intel nmake - u br_gccfi br_unotypes NULL +br bridges\source\cpp_uno\gcc2_freebsd_intel-sjlj nmake - u br_gccfi br_unotypes NULL +br bridges\source\cpp_uno\gcc3_freebsd_intel nmake - u br_gcc3fi br_unotypes NULL br bridges\source\cpp_uno\gcc2_linux_powerpc nmake - u br_gcclp br_unotypes NULL br bridges\source\cpp_uno\gcc3_linux_powerpc nmake - u br_gcclp3 br_unotypes NULL +br bridges\source\cpp_uno\gcc3_linux_s390 nmake - u br_gccl33 br_unotypes NULL br bridges\source\cpp_uno\gcc2_macosx_powerpc nmake - u br_gccmacoxp br_unotypes NULL br bridges\source\cpp_uno\cc50_solaris_sparc nmake - u br_cc50sols br_unotypes NULL br bridges\source\cpp_uno\cc50_solaris_intel nmake - u br_cc50soli br_unotypes NULL @@ -21,4 +24,4 @@ br bridges\source\cpp_uno\gcc2_netbsd_powerpc nmake - u br_gccnp br_unotypes NUL br bridges\source\prot_uno nmake - all br_pruno br_unotypes NULL #br bridges\source\java_uno nmake - all br_java_uno br_rcon NULL br bridges\source\jni_uno nmake - all br_jni_uno br_unotypes NULL -br bridges\source\jni_uno\java nmake - all br_jni_uno_java br_unotypes NULL +br bridges\source\jni_uno\java\com\sun\star\bridges\jni_uno nmake - all br_jni_uno_java br_unotypes NULL diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx index ea4e3f1efb40..de991b741ef6 100644 --- a/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx +++ b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx @@ -2,9 +2,9 @@ * * $RCSfile: except.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: pl $ $Date: 2001-07-05 14:38:52 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:44 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -351,6 +351,13 @@ static void deleteException( void* pExc ) void cc50_solaris_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) { +#if defined DEBUG + OString cstr( + OUStringToOString( + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() ); +#endif typelib_TypeDescription * pTypeDescr = 0; // will be released by deleteException typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType ); @@ -394,24 +401,35 @@ void cc50_solaris_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cp void cc50_solaris_intel_fillUnoException( void* pCppExc, const char* pInfo, - uno_Any* pExc, + uno_Any* pUnoExc, uno_Mapping * pCpp2Uno ) { - OUString aName( OStringToOUString( toUNOname( pInfo ), RTL_TEXTENCODING_ASCII_US ) ); + OString uno_name( toUNOname( pInfo ) ); +#if defined DEBUG + fprintf( stderr, "> c++ exception occured: %s\n", uno_name.getStr() ); +#endif typelib_TypeDescription * pExcTypeDescr = 0; - typelib_typedescription_getByName( - &pExcTypeDescr, - aName.pData ); - if (pExcTypeDescr) + OUString aName( OStringToOUString( uno_name, RTL_TEXTENCODING_ASCII_US ) ); + typelib_typedescription_getByName( &pExcTypeDescr, aName.pData ); + if (0 == pExcTypeDescr) // the thing that should not be + { + RuntimeException aRE( + OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + aName, + Reference< XInterface >() ); + Type const & rType = ::getCppuType( &aRE ); + uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno ); +#if defined _DEBUG + OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_ENSURE( 0, cstr.getStr() ); +#endif + // though this unknown exception leaks now, no user-defined exception + // is ever thrown thru the binary C-UNO dispatcher call stack. + } + else { - // construct cpp exception any - Any aAny( pCppExc, 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 ); + uno_any_constructAndConvert( pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno ); + typelib_typedescription_release( pExcTypeDescr ); } } diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx index 31f01616fd54..f7d98a4809a2 100644 --- a/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx @@ -2,9 +2,9 @@ * * $RCSfile: except.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: pl $ $Date: 2001-07-05 14:36:39 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:45 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -353,6 +353,13 @@ static void deleteException( void* pExc ) void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) { +#if defined DEBUG + OString cstr( + OUStringToOString( + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() ); +#endif typelib_TypeDescription * pTypeDescr = 0; // will be released by deleteException typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType ); @@ -396,24 +403,35 @@ void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cp void cc50_solaris_sparc_fillUnoException( void* pCppExc, const char* pInfo, - uno_Any* pExc, + uno_Any* pUnoExc, uno_Mapping * pCpp2Uno ) { - OUString aName( OStringToOUString( toUNOname( pInfo ), RTL_TEXTENCODING_ASCII_US ) ); + OString uno_name( toUNOname( pInfo ) ); +#if defined DEBUG + fprintf( stderr, "> c++ exception occured: %s\n", uno_name.getStr() ); +#endif typelib_TypeDescription * pExcTypeDescr = 0; - typelib_typedescription_getByName( - &pExcTypeDescr, - aName.pData ); - if (pExcTypeDescr) + OUString aName( OStringToOUString( uno_name, RTL_TEXTENCODING_ASCII_US ) ); + typelib_typedescription_getByName( &pExcTypeDescr, aName.pData ); + if (0 == pExcTypeDescr) // the thing that should not be + { + RuntimeException aRE( + OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + aName, + Reference< XInterface >() ); + Type const & rType = ::getCppuType( &aRE ); + uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno ); +#if defined _DEBUG + OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_ENSURE( 0, cstr.getStr() ); +#endif + // though this unknown exception leaks now, no user-defined exception + // is ever thrown thru the binary C-UNO dispatcher call stack. + } + else { - // construct cpp exception any - Any aAny( pCppExc, 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 ); + uno_any_constructAndConvert( pUnoExc, pCppExc, pExcTypeDescr, pCpp2Uno ); + typelib_typedescription_release( pExcTypeDescr ); } } diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/cpp2uno.cxx new file mode 100644 index 000000000000..c839f41e88a1 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/cpp2uno.cxx @@ -0,0 +1,594 @@ +/************************************************************************* + * + * $RCSfile: cpp2uno.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:52 $ + * + * 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 <malloc.h> +#include <hash_map> + +#include <rtl/alloc.h> +#include <osl/mutex.hxx> + +#include <uno/data.h> +#include <typelib/typedescription.hxx> + +#include <bridges/cpp_uno/bridge.hxx> +#include <bridges/cpp_uno/type_misc.hxx> + +#include "share.hxx" + + +using namespace ::osl; +using namespace ::rtl; +using namespace ::com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; + +//================================================================================================== +static typelib_TypeClass cpp2uno_call( + cppu_cppInterfaceProxy * pThis, + const typelib_TypeDescription * pMemberTypeDescr, + typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return + sal_Int32 nParams, typelib_MethodParameter * pParams, + void ** pCallStack, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + // pCallStack: ret, [return ptr], this, params + char * pCppStack = (char *)(pCallStack +1); + + // return + typelib_TypeDescription * pReturnTypeDescr = 0; + if (pReturnTypeRef) + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + + void * pUnoReturn = 0; + void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need + + if (pReturnTypeDescr) + { + if (cppu_isSimpleType( pReturnTypeDescr )) + { + pUnoReturn = pRegisterReturn; // direct way for simple types + } + else // complex return via ptr (pCppReturn) + { + pCppReturn = *(void **)pCppStack; + pCppStack += sizeof(void *); + + pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr ) + ? alloca( pReturnTypeDescr->nSize ) + : pCppReturn); // direct way + } + } + // pop this + pCppStack += sizeof( void* ); + + // stack space + OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); + // parameters + void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams ); + void ** pCppArgs = pUnoArgs + nParams; + // indizes of values this have to be converted (interface conversion cpp<=>uno) + sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams)); + // type descriptions for reconversions + typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * 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 )) // value + { + pCppArgs[nPos] = pCppStack; + pUnoArgs[nPos] = pCppStack; + switch (pParamTypeDescr->eTypeClass) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_DOUBLE: + pCppStack += sizeof(sal_Int32); // extra long + } + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + else // ptr to complex value | ref + { + pCppArgs[nPos] = *(void **)pCppStack; + + if (! rParam.bIn) // is pure out + { + // uno out is unconstructed mem! + pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ); + pTempIndizes[nTempIndizes] = nPos; + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + // is in/inout + else if (cppu_relatesToInterface( pParamTypeDescr )) + { + uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), + *(void **)pCppStack, pParamTypeDescr, + &pThis->pBridge->aCpp2Uno ); + pTempIndizes[nTempIndizes] = nPos; // has to be reconverted + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + else // direct way + { + pUnoArgs[nPos] = *(void **)pCppStack; + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + } + pCppStack += sizeof(sal_Int32); // standard parameter length + } + + // ExceptionHolder + uno_Any aUnoExc; // Any will be constructed by callee + uno_Any * pUnoExc = &aUnoExc; + + // invoke uno dispatch call + (*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); + + // in case an exception occured... + if (pUnoExc) + { + // destruct temporary in/inout params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + + if (pParams[nIndex].bIn) // is in/inout => was constructed + uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 ); + TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); + } + if (pReturnTypeDescr) + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + + raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any + // is here for dummy + return typelib_TypeClass_VOID; + } + else // else no exception occured... + { + // temporary params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; + + if (pParams[nIndex].bOut) // inout/out + { + // convert and assign + uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); + uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, + &pThis->pBridge->aUno2Cpp ); + } + // destroy temp uno param + uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); + + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + // return + if (pCppReturn) // has complex return + { + if (pUnoReturn != pCppReturn) // needs reconversion + { + uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, + &pThis->pBridge->aUno2Cpp ); + // destroy temp uno return + uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); + } + // complex return ptr is set to eax + *(void **)pRegisterReturn = pCppReturn; + } + if (pReturnTypeDescr) + { + typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass; + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + return eRet; + } + else + return typelib_TypeClass_VOID; + } +} + + +//================================================================================================== +static typelib_TypeClass cpp_mediate( + sal_Int32 nVtableCall, + void ** pCallStack, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); + + // pCallStack: ret adr, [ret *], this, params + // _this_ ptr is patched cppu_XInterfaceProxy object + cppu_cppInterfaceProxy * pCppI = NULL; + if( nVtableCall & 0x80000000 ) + { + nVtableCall &= 0x7fffffff; + pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(pCallStack +2); + } + else + { + pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(pCallStack +1); + } + + typelib_InterfaceTypeDescription * pTypeDescr = pCppI->pTypeDescr; + + OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) + { + throw RuntimeException( + OUString::createFromAscii("illegal vtable index!"), + (XInterface *)pCppI ); + } + + // determine called method + OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; + OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); + + TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); + + typelib_TypeClass eRet; + switch (aMemberDescr.get()->eTypeClass) + { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nVtableCall) + { + // is GET method + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, + 0, 0, // no params + pCallStack, pRegisterReturn ); + } + else + { + // is SET method + typelib_MethodParameter aParam; + aParam.pTypeRef = + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; + aParam.bIn = sal_True; + aParam.bOut = sal_False; + + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + 0, // indicates void return + 1, &aParam, + pCallStack, pRegisterReturn ); + } + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + // is METHOD + switch (nVtableCall) + { + case 1: // acquire() + pCppI->acquireProxy(); // non virtual call! + eRet = typelib_TypeClass_VOID; + break; + case 2: // release() + pCppI->releaseProxy(); // non virtual call! + eRet = typelib_TypeClass_VOID; + break; + case 0: // queryInterface() opt + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() ); + if (pTD) + { + XInterface * pInterface = 0; + (*pCppI->pBridge->pCppEnv->getRegisteredInterface)( + pCppI->pBridge->pCppEnv, + (void **)&pInterface, pCppI->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); + + if (pInterface) + { + ::uno_any_construct( + reinterpret_cast< uno_Any * >( pCallStack[1] ), + &pInterface, pTD, cpp_acquire ); + pInterface->release(); + TYPELIB_DANGER_RELEASE( pTD ); + *(void **)pRegisterReturn = pCallStack[1]; + eRet = typelib_TypeClass_ANY; + break; + } + TYPELIB_DANGER_RELEASE( pTD ); + } + } // else perform queryInterface() + default: + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, + pCallStack, pRegisterReturn ); + } + break; + } + default: + { + throw RuntimeException( + OUString::createFromAscii("no member description found!"), + (XInterface *)pCppI ); + // is here for dummy + eRet = typelib_TypeClass_VOID; + } + } + + return eRet; +} + +//================================================================================================== +/** + * is called on incoming vtable calls + * (called by asm snippets) + */ +static void cpp_vtable_call( int nTableEntry, void** pCallStack ) __attribute__((regparm(2))); + +void cpp_vtable_call( int nTableEntry, void** pCallStack ) +{ + volatile long nRegReturn[2]; + typelib_TypeClass aType = cpp_mediate( nTableEntry, pCallStack, (sal_Int64*)nRegReturn ); + + switch( aType ) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + __asm__( "movl %1, %%edx\n\t" + "movl %0, %%eax\n" + : : "m"(nRegReturn[0]), "m"(nRegReturn[1]) ); + break; + case typelib_TypeClass_FLOAT: + __asm__( "flds %0\n\t" + "fstp %%st(0)\n\t" + "flds %0\n" + : : "m"(*(float *)nRegReturn) ); + break; + case typelib_TypeClass_DOUBLE: + __asm__( "fldl %0\n\t" + "fstp %%st(0)\n\t" + "fldl %0\n" + : : "m"(*(double *)nRegReturn) ); + break; +// case typelib_TypeClass_UNSIGNED_SHORT: +// case typelib_TypeClass_SHORT: +// __asm__( "movswl %0, %%eax\n" +// : : "m"(nRegReturn) ); +// break; + default: + __asm__( "movl %0, %%eax\n" + : : "m"(nRegReturn[0]) ); + break; + } +} + + +//================================================================================================== +class MediateClassData +{ + typedef ::std::hash_map< OUString, void *, OUStringHash > t_classdata_map; + t_classdata_map m_map; + Mutex m_mutex; + +public: + void const * get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () ); + + inline MediateClassData() SAL_THROW( () ) + {} + ~MediateClassData() SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +MediateClassData::~MediateClassData() SAL_THROW( () ) +{ + OSL_TRACE( "> calling ~MediateClassData(): freeing mediate vtables." ); + + for ( t_classdata_map::const_iterator iPos( m_map.begin() ); iPos != m_map.end(); ++iPos ) + { + ::rtl_freeMemory( iPos->second ); + } +} +//-------------------------------------------------------------------------------------------------- +static inline void codeSnippet( char * code, sal_uInt32 vtable_pos, bool simple_ret_type ) SAL_THROW( () ) +{ + if (! simple_ret_type) + vtable_pos |= 0x80000000; + OSL_ASSERT( sizeof (long) == 4 ); + // mov $nPos, %eax + *code++ = 0xb8; + *(long *)code = vtable_pos; + code += sizeof (long); + // mov %esp, %edx + *code++ = 0x89; + *code++ = 0xe2; + // jmp cpp_vtable_call + *code++ = 0xe9; + *(long *)code = ((char *)cpp_vtable_call) - code - sizeof (long); +} +//__________________________________________________________________________________________________ +void const * MediateClassData::get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () ) +{ + void * buffer; + + // avoiding locked counts + OUString const & unoName = *(OUString const *)&((typelib_TypeDescription *)pTD)->pTypeName; + { + MutexGuard aGuard( m_mutex ); + t_classdata_map::const_iterator iFind( m_map.find( unoName ) ); + if (iFind == m_map.end()) + { + // create new vtable + sal_Int32 nSlots = pTD->nMapFunctionIndexToMemberIndex; + buffer = ::rtl_allocateMemory( ((2+ nSlots) * sizeof (void *)) + (nSlots *20) ); + + ::std::pair< t_classdata_map::iterator, bool > insertion( + m_map.insert( t_classdata_map::value_type( unoName, buffer ) ) ); + OSL_ENSURE( insertion.second, "### inserting new vtable buffer failed?!" ); + + void ** slots = (void **)buffer; + *slots++ = 0; + *slots++ = 0; // rtti + char * code = (char *)(slots + nSlots); + + sal_uInt32 vtable_pos = 0; + sal_Int32 nAllMembers = pTD->nAllMembers; + typelib_TypeDescriptionReference ** ppAllMembers = pTD->ppAllMembers; + for ( sal_Int32 nPos = 0; nPos < nAllMembers; ++nPos ) + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ppAllMembers[ nPos ] ); + OSL_ASSERT( pTD ); + if (typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass) + { + bool simple_ret = cppu_isSimpleType( + ((typelib_InterfaceAttributeTypeDescription *)pTD)->pAttributeTypeRef->eTypeClass ); + // get method + *slots++ = code; + codeSnippet( code, vtable_pos++, simple_ret ); + code += 20; + if (! ((typelib_InterfaceAttributeTypeDescription *)pTD)->bReadOnly) + { + // set method + *slots++ = code; + codeSnippet( code, vtable_pos++, true ); + code += 20; + } + } + else + { + bool simple_ret = cppu_isSimpleType( + ((typelib_InterfaceMethodTypeDescription *)pTD)->pReturnTypeRef->eTypeClass ); + *slots++ = code; + codeSnippet( code, vtable_pos++, simple_ret ); + code += 20; + } + TYPELIB_DANGER_RELEASE( pTD ); + } + OSL_ASSERT( vtable_pos == nSlots ); + } + else + { + buffer = iFind->second; + } + } + + return ((void **)buffer +2); +} + +//================================================================================================== +void SAL_CALL cppu_cppInterfaceProxy_patchVtable( + XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) throw () +{ + static MediateClassData * s_pMediateClassData = 0; + if (! s_pMediateClassData) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pMediateClassData) + { +#ifdef LEAK_STATIC_DATA + s_pMediateClassData = new MediateClassData(); +#else + static MediateClassData s_aMediateClassData; + s_pMediateClassData = &s_aMediateClassData; +#endif + } + } + *(void const **)pCppI = s_pMediateClassData->get_vtable( pTypeDescr ); +} + +} + +extern "C" +{ +//################################################################################################## +sal_Bool SAL_CALL component_canUnload( TimeValue * pTime ) + SAL_THROW_EXTERN_C() +{ + return CPPU_CURRENT_NAMESPACE::g_moduleCount.canUnload( + &CPPU_CURRENT_NAMESPACE::g_moduleCount, pTime ); +} +//################################################################################################## +void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) + SAL_THROW_EXTERN_C() +{ + CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( + pCppEnv ); +} +//################################################################################################## +void SAL_CALL uno_ext_getMapping( + uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) + SAL_THROW_EXTERN_C() +{ + CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( + ppMapping, pFrom, pTo ); +} +} diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/except.cxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/except.cxx new file mode 100644 index 000000000000..91c2a1ad1fa3 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/except.cxx @@ -0,0 +1,317 @@ +/************************************************************************* + * + * $RCSfile: except.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:52 $ + * + * 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 <stdio.h> +#include <dlfcn.h> +#include <cxxabi.h> +#include <hash_map> + +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> + +#include <bridges/cpp_uno/bridge.hxx> +#include <typelib/typedescription.hxx> +#include <uno/any2.h> + +#include "share.hxx" + + +using namespace ::std; +using namespace ::osl; +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::__cxxabiv1; + + +namespace CPPU_CURRENT_NAMESPACE +{ + +void dummy_can_throw_anything( char const * ) +{ +} + +//================================================================================================== +static OUString toUNOname( char const * p ) SAL_THROW( () ) +{ +#ifdef DEBUG + char const * start = p; +#endif + + // example: N3com3sun4star4lang24IllegalArgumentExceptionE + + OUStringBuffer buf( 64 ); + OSL_ASSERT( 'N' == *p ); + ++p; // skip N + + while ('E' != *p) + { + // read chars count + long n = (*p++ - '0'); + while ('0' <= *p && '9' >= *p) + { + n *= 10; + n += (*p++ - '0'); + } + buf.appendAscii( p, n ); + p += n; + if ('E' != *p) + buf.append( (sal_Unicode)'.' ); + } + +#ifdef DEBUG + OUString ret( buf.makeStringAndClear() ); + OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() ); + return ret; +#else + return buf.makeStringAndClear(); +#endif +} + +//================================================================================================== +class RTTI +{ + typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map; + + Mutex m_mutex; + t_rtti_map m_rttis; + t_rtti_map m_generatedRttis; + + void * m_hApp; + +public: + RTTI() SAL_THROW( () ); + ~RTTI() SAL_THROW( () ); + + type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +RTTI::RTTI() SAL_THROW( () ) + : m_hApp( dlopen( 0, RTLD_LAZY ) ) +{ +} +//__________________________________________________________________________________________________ +RTTI::~RTTI() SAL_THROW( () ) +{ + dlclose( m_hApp ); +} + +//__________________________________________________________________________________________________ +type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () ) +{ + type_info * rtti; + + OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName; + + MutexGuard guard( m_mutex ); + t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) ); + if (iFind == m_rttis.end()) + { + // RTTI symbol + OStringBuffer buf( 64 ); + buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") ); + sal_Int32 index = 0; + do + { + OUString token( unoName.getToken( 0, '.', index ) ); + buf.append( token.getLength() ); + OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) ); + buf.append( c_token ); + } + while (index >= 0); + buf.append( 'E' ); + + OString symName( buf.makeStringAndClear() ); + rtti = (type_info *)dlsym( m_hApp, symName.getStr() ); + + if (rtti) + { + pair< t_rtti_map::iterator, bool > insertion( + m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); + OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" ); + } + else + { + // try to lookup the symbol in the generated rtti map + t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) ); + if (iFind == m_generatedRttis.end()) + { + // we must generate it ! + // symbol and rtti-name is nearly identical, + // the symbol is prefixed with _ZTI + char const * rttiName = symName.getStr() +4; +#ifdef DEBUG + fprintf( stderr,"generated rtti for %s\n", rttiName ); +#endif + if (pTypeDescr->pBaseTypeDescription) + { + // ensure availability of base + type_info * base_rtti = getRTTI( + (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription ); + rtti = new __si_class_type_info( + strdup( rttiName ), (__class_type_info *)base_rtti ); + } + else + { + // this class has no base class + rtti = new __class_type_info( strdup( rttiName ) ); + } + + pair< t_rtti_map::iterator, bool > insertion( + m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); + OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" ); + } + else // taking already generated rtti + { + rtti = iFind->second; + } + } + } + else + { + rtti = iFind->second; + } + + return rtti; +} + +//-------------------------------------------------------------------------------------------------- +static void deleteException( void * pExc ) +{ + __cxa_exception const * header = ((__cxa_exception const *)pExc - 1); + typelib_TypeDescription * pTD = 0; + OUString unoName( toUNOname( header->exceptionType->name() ) ); + ::typelib_typedescription_getByName( &pTD, unoName.pData ); + OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" ); + if (pTD) + { + ::uno_destructData( pExc, pTD, cpp_release ); + ::typelib_typedescription_release( pTD ); + } +} + +//================================================================================================== +void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +{ + void * pCppExc; + type_info * rtti; + + { + // construct cpp exception object + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType ); + OSL_ASSERT( pTypeDescr ); + if (! pTypeDescr) + terminate(); + + pCppExc = __cxa_allocate_exception( pTypeDescr->nSize ); + ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); + + // destruct uno exception + ::uno_any_destruct( pUnoExc, 0 ); + // avoiding locked counts + static RTTI * s_rtti = 0; + if (! s_rtti) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if (! s_rtti) + { +#ifdef LEAK_STATIC_DATA + s_rtti = new RTTI(); +#else + static RTTI rtti_data; + s_rtti = &rtti_data; +#endif + } + } + rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + OSL_ENSURE( rtti, "### no rtti for throwing exception!" ); + if (! rtti) + terminate(); + } + + __cxa_throw( pCppExc, rtti, deleteException ); +} + +//================================================================================================== +void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno ) +{ + OSL_ENSURE( header, "### no exception header!!!" ); + if (! header) + terminate(); + + typelib_TypeDescription * pExcTypeDescr = 0; + OUString unoName( toUNOname( header->exceptionType->name() ) ); + ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData ); + OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" ); + if (! pExcTypeDescr) + terminate(); + + // construct uno exception any + ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno ); + ::typelib_typedescription_release( pExcTypeDescr ); +} + +} + diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/makefile.mk b/bridges/source/cpp_uno/gcc3_freebsd_intel/makefile.mk new file mode 100644 index 000000000000..e6e46904ef5f --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/makefile.mk @@ -0,0 +1,112 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.2 $ +# +# last change: $Author: hr $ $Date: 2003-03-18 19:06:52 $ +# +# 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): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=bridges +TARGET=gcc3_uno +LIBTARGET=no +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCFREEBSDIgcc3" + +.IF "$(cppu_no_leak)" == "" +CFLAGS += -DLEAK_STATIC_DATA +.ENDIF + +CFLAGSNOOPT=-O0 + +SLOFILES= \ + $(SLO)$/except.obj \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj + +SHL1TARGET= $(TARGET) + +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB=i$(TARGET) +SHL1VERSIONMAP=..$/..$/bridge_exports.map + +SHL1OBJS= \ + $(SLO)$/except.obj \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) + +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/bridges/source/cpp_uno/gcc3_freebsd_intel/share.hxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/share.hxx new file mode 100644 index 000000000000..d262093557eb --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/share.hxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * $RCSfile: share.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:53 $ + * + * 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_freebsd_intel/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_freebsd_intel/uno2cpp.cxx new file mode 100644 index 000000000000..c915d408fff9 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_freebsd_intel/uno2cpp.cxx @@ -0,0 +1,450 @@ +/************************************************************************* + * + * $RCSfile: uno2cpp.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:53 $ + * + * 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 <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, + sal_Int32 * pStackLongs, + sal_Int32 nStackLongs ) +{ + // parameter list is mixed list of * and values + // reference parameters are pointers + + OSL_ENSURE( pStackLongs && pThis, "### null ptr!" ); + OSL_ENSURE( (sizeof(void *) == 4) && (sizeof(sal_Int32) == 4), "### unexpected size of int!" ); + OSL_ENSURE( nStackLongs && pStackLongs, "### no stack in callVirtualMethod !" ); + + // never called + if (! pThis) dummy_can_throw_anything("xxx"); // address something + + volatile long edx = 0, eax = 0; // for register returns + asm volatile ( + // copy values + "mov %0, %%eax\n\t" + "mov %%eax, %%edx\n\t" + "dec %%edx\n\t" + "shl $2, %%edx\n\t" + "add %1, %%edx\n" + "Lcopy:\n\t" + "pushl 0(%%edx)\n\t" + "sub $4, %%edx\n\t" + "dec %%eax\n\t" + "jne Lcopy\n\t" + // do the actual call + "mov %2, %%edx\n\t" + "mov 0(%%edx), %%edx\n\t" + "mov %3, %%eax\n\t" + "shl $2, %%eax\n\t" + "add %%eax, %%edx\n\t" + "mov 0(%%edx), %%edx\n\t" + "call *%%edx\n\t" + // save return registers + "mov %%eax, %4\n\t" + "mov %%edx, %5\n\t" + // cleanup stack + "mov %0, %%eax\n\t" + "shl $2, %%eax\n\t" + "add %%eax, %%esp\n\t" + : + : "m"(nStackLongs), "m"(pStackLongs), "m"(pThis), "m"(nVtableIndex), "m"(eax), "m"(edx) + : "eax", "edx" ); + + switch( eReturnType ) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + ((long*)pRegisterReturn)[1] = edx; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_ENUM: + ((long*)pRegisterReturn)[0] = eax; + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(unsigned short*)pRegisterReturn = eax; + break; + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + *(unsigned char*)pRegisterReturn = eax; + break; + case typelib_TypeClass_FLOAT: + asm ( "fstps %0" : : "m"(*(char *)pRegisterReturn) ); + break; + case typelib_TypeClass_DOUBLE: + asm ( "fstpl %0\n\t" : : "m"(*(char *)pRegisterReturn) ); + 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; + + // 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 + pCppStack += sizeof(void *); + } + } + // push this + *(void**)pCppStack = pThis->pCppI; + pCppStack += sizeof( void* ); + + // 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) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_DOUBLE: + 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 ); + } + } + pCppStack += sizeof(sal_Int32); // standard parameter length + } + + try + { + OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 3), "UNALIGNED STACK !!! (Please DO panic)" ); + callVirtualMethod( + pThis->pCppI, nVtableCall, + pCppReturn, pReturnTypeDescr->eTypeClass, + (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 ); + } + } +} + +} + diff --git a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx index 87ca1e01495e..1cfd8c78770e 100644 --- a/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_intel/except.cxx @@ -2,9 +2,9 @@ * * $RCSfile: except.cxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: dbo $ $Date: 2001-11-08 12:35:28 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:54 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -253,6 +253,13 @@ static void deleteException( void * pExc ) //================================================================================================== void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) { +#if defined DEBUG + OString cstr( + OUStringToOString( + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() ); +#endif void * pCppExc; type_info * rtti; @@ -262,7 +269,12 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType ); OSL_ASSERT( pTypeDescr ); if (! pTypeDescr) - terminate(); + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) + + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + Reference< XInterface >() ); + } pCppExc = __cxa_allocate_exception( pTypeDescr->nSize ); ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); @@ -288,29 +300,59 @@ void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) TYPELIB_DANGER_RELEASE( pTypeDescr ); OSL_ENSURE( rtti, "### no rtti for throwing exception!" ); if (! rtti) - terminate(); + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) + + *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ), + Reference< XInterface >() ); + } } __cxa_throw( pCppExc, rtti, deleteException ); } //================================================================================================== -void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno ) +void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno ) { - OSL_ENSURE( header, "### no exception header!!!" ); if (! header) - terminate(); + { + RuntimeException aRE( + OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ), + Reference< XInterface >() ); + Type const & rType = ::getCppuType( &aRE ); + uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno ); +#if defined _DEBUG + OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_ENSURE( 0, cstr.getStr() ); +#endif + return; + } typelib_TypeDescription * pExcTypeDescr = 0; OUString unoName( toUNOname( header->exceptionType->name() ) ); - ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData ); - OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" ); - if (! pExcTypeDescr) - terminate(); - - // construct uno exception any - ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno ); - ::typelib_typedescription_release( pExcTypeDescr ); +#if defined DEBUG + OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() ); +#endif + typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData ); + if (0 == pExcTypeDescr) + { + RuntimeException aRE( + OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName, + Reference< XInterface >() ); + Type const & rType = ::getCppuType( &aRE ); + uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno ); +#if defined _DEBUG + OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) ); + OSL_ENSURE( 0, cstr.getStr() ); +#endif + } + else + { + // construct uno exception any + uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno ); + typelib_typedescription_release( pExcTypeDescr ); + } } } diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx new file mode 100644 index 000000000000..130f86da2165 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_s390/cpp2uno.cxx @@ -0,0 +1,759 @@ +/************************************************************************* + * + * $RCSfile: cpp2uno.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:54 $ + * + * 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 <malloc.h> +#include <hash_map> + +#include <rtl/alloc.h> +#include <osl/mutex.hxx> + +#include <uno/data.h> +#include <typelib/typedescription.hxx> + +#include <bridges/cpp_uno/bridge.hxx> +#include <bridges/cpp_uno/type_misc.hxx> + +#include "share.hxx" + + +using namespace ::osl; +using namespace ::rtl; +using namespace ::com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT; + +//================================================================================================== +static typelib_TypeClass cpp2uno_call( + cppu_cppInterfaceProxy * pThis, + const typelib_TypeDescription * pMemberTypeDescr, + typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return + sal_Int32 nParams, typelib_MethodParameter * pParams, + void ** gpreg, void ** fpreg, void ** ovrflw, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + int ng = 0; //number of gpr registers used + int nf = 0; //number of fpr regsiters used + void ** pCppStack; //temporary stack pointer + + // gpreg: [ret *], this, [gpr params] + // fpreg: [fpr params] + // ovrflw: [gpr or fpr params (properly aligned)] + + // return + typelib_TypeDescription * pReturnTypeDescr = 0; + if (pReturnTypeRef) + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + + void * pUnoReturn = 0; + void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need + + if (pReturnTypeDescr) + { + if (cppu_isSimpleType( pReturnTypeDescr )) + { + pUnoReturn = pRegisterReturn; // direct way for simple types + } + else // complex return via ptr (pCppReturn) + { + pCppReturn = *(void **)gpreg; + gpreg++; + ng++; + + pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr ) + ? alloca( pReturnTypeDescr->nSize ) + : pCppReturn); // direct way + } + } + // pop this + gpreg++; + ng++; + + // stack space + OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" ); + // parameters + void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams ); + void ** pCppArgs = pUnoArgs + nParams; + // indizes of values this have to be converted (interface conversion cpp<=>uno) + sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams)); + // type descriptions for reconversions + typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * 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 )) // value + { + + switch (pParamTypeDescr->eTypeClass) + { + + case typelib_TypeClass_DOUBLE: + if (nf < 2) { + pCppArgs[nPos] = fpreg; + pUnoArgs[nPos] = fpreg; + nf++; + fpreg += 2; + } else { + pCppArgs[nPos] = ovrflw; + pUnoArgs[nPos] = ovrflw; + ovrflw += 2; + } + break; + + case typelib_TypeClass_FLOAT: + // fpreg are all double values so need to + // modify fpreg to be a single word float value + if (nf < 2) { +// float tmp = (float) (*((double *)fpreg)); +// (*((float *) fpreg)) = tmp; + pCppArgs[nPos] = fpreg; + pUnoArgs[nPos] = fpreg; + nf++; + fpreg += 2; + } else { + pCppArgs[nPos] = ovrflw; + pUnoArgs[nPos] = ovrflw; + ovrflw += 1; + } + break; + + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (ng < 4) { + pCppArgs[nPos] = gpreg; + pUnoArgs[nPos] = gpreg; + ng += 2; + gpreg += 2; + } else { + pCppArgs[nPos] = ovrflw; + pUnoArgs[nPos] = ovrflw; + ovrflw += 2; + } + break; + + case typelib_TypeClass_BYTE: + case typelib_TypeClass_BOOLEAN: + if (ng < 5) { + pCppArgs[nPos] = (((char *)gpreg) + 3); + pUnoArgs[nPos] = (((char *)gpreg) + 3); + ng++; + gpreg++; + } else { + pCppArgs[nPos] = (((char *)ovrflw) + 3); + pUnoArgs[nPos] = (((char *)ovrflw) + 3); + ovrflw++; + } + break; + + + case typelib_TypeClass_CHAR: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + if (ng < 5) { + pCppArgs[nPos] = (((char *)gpreg)+ 2); + pUnoArgs[nPos] = (((char *)gpreg)+ 2); + ng++; + gpreg++; + } else { + pCppArgs[nPos] = (((char *)ovrflw) + 2); + pUnoArgs[nPos] = (((char *)ovrflw) + 2); + ovrflw++; + } + break; + + + default: + if (ng < 5) { + pCppArgs[nPos] = gpreg; + pUnoArgs[nPos] = gpreg; + ng++; + gpreg++; + } else { + pCppArgs[nPos] = ovrflw; + pUnoArgs[nPos] = ovrflw; + ovrflw++; + } + break; + + } + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + else // ptr to complex value | ref + { + + if (ng < 5) { + pCppArgs[nPos] = *(void **)gpreg; + pCppStack = gpreg; + ng++; + gpreg++; + } else { + pCppArgs[nPos] = *(void **)ovrflw; + pCppStack = ovrflw; + ovrflw++; + } + + if (! rParam.bIn) // is pure out + { + // uno out is unconstructed mem! + pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ); + pTempIndizes[nTempIndizes] = nPos; + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + // is in/inout + else if (cppu_relatesToInterface( pParamTypeDescr )) + { + uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ), + *(void **)pCppStack, pParamTypeDescr, + &pThis->pBridge->aCpp2Uno ); + pTempIndizes[nTempIndizes] = nPos; // has to be reconverted + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + else // direct way + { + pUnoArgs[nPos] = *(void **)pCppStack; + // no longer needed + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + } + } + + // ExceptionHolder + uno_Any aUnoExc; // Any will be constructed by callee + uno_Any * pUnoExc = &aUnoExc; + + // invoke uno dispatch call + (*pThis->pUnoI->pDispatcher)( pThis->pUnoI, pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc ); + + // in case an exception occured... + if (pUnoExc) + { + // destruct temporary in/inout params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + + if (pParams[nIndex].bIn) // is in/inout => was constructed + uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 ); + TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); + } + if (pReturnTypeDescr) + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + + raiseException( &aUnoExc, &pThis->pBridge->aUno2Cpp ); // has to destruct the any + // is here for dummy + return typelib_TypeClass_VOID; + } + else // else no exception occured... + { + // temporary params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes]; + + if (pParams[nIndex].bOut) // inout/out + { + // convert and assign + uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release ); + uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr, + &pThis->pBridge->aUno2Cpp ); + } + // destroy temp uno param + uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); + + TYPELIB_DANGER_RELEASE( pParamTypeDescr ); + } + // return + if (pCppReturn) // has complex return + { + if (pUnoReturn != pCppReturn) // needs reconversion + { + uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr, + &pThis->pBridge->aUno2Cpp ); + // destroy temp uno return + uno_destructData( pUnoReturn, pReturnTypeDescr, 0 ); + } + // complex return ptr is set to return reg + *(void **)pRegisterReturn = pCppReturn; + } + if (pReturnTypeDescr) + { + typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass; + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + return eRet; + } + else + return typelib_TypeClass_VOID; + } +} + + +//================================================================================================== +static typelib_TypeClass cpp_mediate( + sal_Int32 nVtableCall, + void ** gpreg, void ** fpreg, void ** ovrflw, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); + + // gpreg: [ret *], this, [other gpr params] + // fpreg: [fpr params] + // ovrflw: [gpr or fpr params (properly aligned)] + + // _this_ ptr is patched cppu_XInterfaceProxy object + cppu_cppInterfaceProxy * pCppI = NULL; + if( nVtableCall & 0x80000000 ) + { + nVtableCall &= 0x7fffffff; + pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(gpreg +1); + } + else + { + pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(gpreg); + } + + typelib_InterfaceTypeDescription * pTypeDescr = pCppI->pTypeDescr; + + OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) + { + throw RuntimeException( + OUString::createFromAscii("illegal vtable index!"), + (XInterface *)pCppI ); + } + + // determine called method + OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; + OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!" ); + + TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] ); + + typelib_TypeClass eRet; + switch (aMemberDescr.get()->eTypeClass) + { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nVtableCall) + { + // is GET method + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef, + 0, 0, // no params + gpreg, fpreg, ovrflw, pRegisterReturn ); + } + else + { + // is SET method + typelib_MethodParameter aParam; + aParam.pTypeRef = + ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef; + aParam.bIn = sal_True; + aParam.bOut = sal_False; + + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + 0, // indicates void return + 1, &aParam, + gpreg, fpreg, ovrflw, pRegisterReturn ); + } + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + // is METHOD + switch (nVtableCall) + { + case 1: // acquire() + pCppI->acquireProxy(); // non virtual call! + eRet = typelib_TypeClass_VOID; + break; + case 2: // release() + pCppI->releaseProxy(); // non virtual call! + eRet = typelib_TypeClass_VOID; + break; + case 0: // queryInterface() opt + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( gpreg[2] )->getTypeLibType() ); + if (pTD) + { + XInterface * pInterface = 0; + (*pCppI->pBridge->pCppEnv->getRegisteredInterface)( + pCppI->pBridge->pCppEnv, + (void **)&pInterface, pCppI->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); + + if (pInterface) + { + ::uno_any_construct( + reinterpret_cast< uno_Any * >( gpreg[0] ), + &pInterface, pTD, cpp_acquire ); + pInterface->release(); + TYPELIB_DANGER_RELEASE( pTD ); + *(void **)pRegisterReturn = gpreg[0]; + eRet = typelib_TypeClass_ANY; + break; + } + TYPELIB_DANGER_RELEASE( pTD ); + } + } // else perform queryInterface() + default: + eRet = cpp2uno_call( + pCppI, aMemberDescr.get(), + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, + gpreg, fpreg, ovrflw, pRegisterReturn ); + } + break; + } + default: + { + throw RuntimeException( + OUString::createFromAscii("no member description found!"), + (XInterface *)pCppI ); + // is here for dummy + eRet = typelib_TypeClass_VOID; + } + } + + return eRet; +} + +//================================================================================================== +/** + * is called on incoming vtable calls + * (called by asm snippets) + */ +static void cpp_vtable_call( int nTableEntry, void** gpregptr, void** fpregptr, void** ovrflw) +{ + sal_Int32 gpreg[8]; + double fpreg[8]; + + memcpy( gpreg, gpregptr, 32); + memcpy( fpreg, fpregptr, 64); + + volatile long nRegReturn[2]; + + sal_Bool bComplex = nTableEntry & 0x80000000 ? sal_True : sal_False; + + typelib_TypeClass aType = + cpp_mediate( nTableEntry, (void**)gpreg, (void**)fpreg, ovrflw, (sal_Int64*)nRegReturn ); + + switch( aType ) + { + + // move return value into register space + // (will be loaded by machine code snippet) + + case typelib_TypeClass_BOOLEAN: + { + unsigned long tmp = (unsigned long)(*(unsigned char *)nRegReturn); + __asm__ volatile ( "l 2,%0\n\t" : : + "m"(tmp) : "2" ); + break; + } + case typelib_TypeClass_BYTE: + { + long tmp = (long)(*(signed char *)nRegReturn); + __asm__ volatile ( "l 2,%0\n\t" : : + "m"(tmp) : "2" ); + break; + } + case typelib_TypeClass_CHAR: + case typelib_TypeClass_UNSIGNED_SHORT: + { + unsigned long tmp = (unsigned long)(*(unsigned short *)nRegReturn); + __asm__ volatile ( "l 2,%0\n\t" : : + "m"(tmp) : "2" ); + break; + } + case typelib_TypeClass_SHORT: + { + long tmp = (long)(*(short *)nRegReturn); + __asm__ volatile ( "l 2,%0\n\t" : : + "m"(tmp) : "2" ); + break; + } + case typelib_TypeClass_FLOAT: + __asm__ volatile ( "le 0,%0\n\t" : : + "m" (*((float*)nRegReturn)) : "16" ); + break; + + case typelib_TypeClass_DOUBLE: + __asm__ volatile ( "ld 0,%0\n\t" : : + "m" (*((double*)nRegReturn)) : "16" ); + break; + + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + __asm__ volatile ( "lm 2,3,%0\n\t" : : + "m"(nRegReturn[0]) : "2", "3" ); + break; + + default: + __asm__ volatile ( "l 2,%0\n\t" : : + "m"(nRegReturn[0]) : "2" ); + break; + } +} + + +//================================================================================================== +class MediateClassData +{ + typedef ::std::hash_map< OUString, void *, OUStringHash > t_classdata_map; + t_classdata_map m_map; + Mutex m_mutex; + +public: + void const * get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () ); + + inline MediateClassData() SAL_THROW( () ) + {} + ~MediateClassData() SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +MediateClassData::~MediateClassData() SAL_THROW( () ) +{ + OSL_TRACE( "> calling ~MediateClassData(): freeing mediate vtables." ); + + for ( t_classdata_map::const_iterator iPos( m_map.begin() ); iPos != m_map.end(); ++iPos ) + { + ::rtl_freeMemory( iPos->second ); + } +} +//-------------------------------------------------------------------------------------------------- +static inline void codeSnippet( long * code, sal_uInt32 vtable_pos, bool simple_ret_type ) SAL_THROW( () ) +{ + if (! simple_ret_type) + vtable_pos |= 0x80000000; + OSL_ASSERT( sizeof (long) == 4 ); + + /* generate this code */ + // lr %r0,%r13 + // bras %r13,0x6 + // .long cpp_vtable_call + // .long vtable_pos + // stm %r2,%r6,8(%r15) + // std %f0,64(%r15) + // std %f2,72(%r15) + + // l %r2,4(%r13) + // la %r3,8(%r15) + // la %r4,64(%r15) + // la %r5,96(%r15) + // l %r1,0(%r13) + // lr %r13,%r0 + // br %r1 + + + * ((short*)code)++ = 0x180d; + * code++ = 0xa7d50006; + * code++ = cpp_vtable_call; + * code++ = vtable_pos; + * code++ = 0x9026f008; + * code++ = 0x6000f040; + * code++ = 0x6020f048; + * code++ = 0x5820d004; + * code++ = 0x4130f008; + * code++ = 0x4140f040; + * code++ = 0x4150f060; + * code++ = 0x5810d000; + * ((short*)code)++ = 0x18d0; + * ((short*)code)++ = 0x07f1; + +} +//__________________________________________________________________________________________________ +void const * MediateClassData::get_vtable( typelib_InterfaceTypeDescription * pTD ) SAL_THROW( () ) +{ + void * buffer; + const int nSnippetSize = 50; + + // avoiding locked counts + OUString const & unoName = *(OUString const *)&((typelib_TypeDescription *)pTD)->pTypeName; + { + MutexGuard aGuard( m_mutex ); + t_classdata_map::const_iterator iFind( m_map.find( unoName ) ); + if (iFind == m_map.end()) + { + // create new vtable + sal_Int32 nSlots = pTD->nMapFunctionIndexToMemberIndex; + buffer = ::rtl_allocateMemory( ((2+ nSlots) * sizeof (void *)) + (nSlots *nSnippetSize) ); + + ::std::pair< t_classdata_map::iterator, bool > insertion( + m_map.insert( t_classdata_map::value_type( unoName, buffer ) ) ); + OSL_ENSURE( insertion.second, "### inserting new vtable buffer failed?!" ); + + void ** slots = (void **)buffer; + *slots++ = 0; + *slots++ = 0; // rtti + char * code = (char *)(slots + nSlots); + + sal_uInt32 vtable_pos = 0; + sal_Int32 nAllMembers = pTD->nAllMembers; + typelib_TypeDescriptionReference ** ppAllMembers = pTD->ppAllMembers; + for ( sal_Int32 nPos = 0; nPos < nAllMembers; ++nPos ) + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ppAllMembers[ nPos ] ); + OSL_ASSERT( pTD ); + if (typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass) + { + bool simple_ret = cppu_isSimpleType( + ((typelib_InterfaceAttributeTypeDescription *)pTD)->pAttributeTypeRef->eTypeClass ); + // get method + *slots = code; + codeSnippet( (long *)code, vtable_pos++, simple_ret ); + code += nSnippetSize; + slots++; + if (! ((typelib_InterfaceAttributeTypeDescription *)pTD)->bReadOnly) + { + // set method + *slots = code; + codeSnippet( (long *)code, vtable_pos++, true ); + code += nSnippetSize; + slots++; + } + } + else + { + bool simple_ret = cppu_isSimpleType( + ((typelib_InterfaceMethodTypeDescription *)pTD)->pReturnTypeRef->eTypeClass ); + *slots = code; + codeSnippet( (long *)code, vtable_pos++, simple_ret ); + code += nSnippetSize; + slots++; + } + TYPELIB_DANGER_RELEASE( pTD ); + } + OSL_ASSERT( vtable_pos == nSlots ); + } + else + { + buffer = iFind->second; + } + } + + return ((void **)buffer +2); +} + +//================================================================================================== +void SAL_CALL cppu_cppInterfaceProxy_patchVtable( + XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) throw () +{ + static MediateClassData * s_pMediateClassData = 0; + if (! s_pMediateClassData) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pMediateClassData) + { +#ifdef LEAK_STATIC_DATA + s_pMediateClassData = new MediateClassData(); +#else + static MediateClassData s_aMediateClassData; + s_pMediateClassData = &s_aMediateClassData; +#endif + } + } + *(void const **)pCppI = s_pMediateClassData->get_vtable( pTypeDescr ); +} + +} + +extern "C" +{ +//################################################################################################## +sal_Bool SAL_CALL component_canUnload( TimeValue * pTime ) + SAL_THROW_EXTERN_C() +{ + return CPPU_CURRENT_NAMESPACE::g_moduleCount.canUnload( + &CPPU_CURRENT_NAMESPACE::g_moduleCount, pTime ); +} +//################################################################################################## +void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) + SAL_THROW_EXTERN_C() +{ + CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( + pCppEnv ); +} +//################################################################################################## +void SAL_CALL uno_ext_getMapping( + uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) + SAL_THROW_EXTERN_C() +{ + CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( + ppMapping, pFrom, pTo ); +} +} diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx new file mode 100644 index 000000000000..85faa833de4e --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_s390/except.cxx @@ -0,0 +1,317 @@ +/************************************************************************* + * + * $RCSfile: except.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:55 $ + * + * 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 <stdio.h> +#include <dlfcn.h> +#include <cxxabi.h> +#include <hash_map> + +#include <rtl/strbuf.hxx> +#include <rtl/ustrbuf.hxx> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> + +#include <bridges/cpp_uno/bridge.hxx> +#include <typelib/typedescription.hxx> +#include <uno/any2.h> + +#include "share.hxx" + + +using namespace ::std; +using namespace ::osl; +using namespace ::rtl; +using namespace ::com::sun::star::uno; +using namespace ::__cxxabiv1; + + +namespace CPPU_CURRENT_NAMESPACE +{ + +void dummy_can_throw_anything( char const * ) +{ +} + +//================================================================================================== +static OUString toUNOname( char const * p ) SAL_THROW( () ) +{ +#ifdef DEBUG + char const * start = p; +#endif + + // example: N3com3sun4star4lang24IllegalArgumentExceptionE + + OUStringBuffer buf( 64 ); + OSL_ASSERT( 'N' == *p ); + ++p; // skip N + + while ('E' != *p) + { + // read chars count + long n = (*p++ - '0'); + while ('0' <= *p && '9' >= *p) + { + n *= 10; + n += (*p++ - '0'); + } + buf.appendAscii( p, n ); + p += n; + if ('E' != *p) + buf.append( (sal_Unicode)'.' ); + } + +#ifdef DEBUG + OUString ret( buf.makeStringAndClear() ); + OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) ); + fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() ); + return ret; +#else + return buf.makeStringAndClear(); +#endif +} + +//================================================================================================== +class RTTI +{ + typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map; + + Mutex m_mutex; + t_rtti_map m_rttis; + t_rtti_map m_generatedRttis; + + void * m_hApp; + +public: + RTTI() SAL_THROW( () ); + ~RTTI() SAL_THROW( () ); + + type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () ); +}; +//__________________________________________________________________________________________________ +RTTI::RTTI() SAL_THROW( () ) + : m_hApp( dlopen( 0, RTLD_LAZY ) ) +{ +} +//__________________________________________________________________________________________________ +RTTI::~RTTI() SAL_THROW( () ) +{ + dlclose( m_hApp ); +} + +//__________________________________________________________________________________________________ +type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () ) +{ + type_info * rtti; + + OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName; + + MutexGuard guard( m_mutex ); + t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) ); + if (iFind == m_rttis.end()) + { + // RTTI symbol + OStringBuffer buf( 64 ); + buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") ); + sal_Int32 index = 0; + do + { + OUString token( unoName.getToken( 0, '.', index ) ); + buf.append( token.getLength() ); + OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) ); + buf.append( c_token ); + } + while (index >= 0); + buf.append( 'E' ); + + OString symName( buf.makeStringAndClear() ); + rtti = (type_info *)dlsym( m_hApp, symName.getStr() ); + + if (rtti) + { + pair< t_rtti_map::iterator, bool > insertion( + m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); + OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" ); + } + else + { + // try to lookup the symbol in the generated rtti map + t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) ); + if (iFind == m_generatedRttis.end()) + { + // we must generate it ! + // symbol and rtti-name is nearly identical, + // the symbol is prefixed with _ZTI + char const * rttiName = symName.getStr() +4; +#ifdef DEBUG + fprintf( stderr,"generated rtti for %s\n", rttiName ); +#endif + if (pTypeDescr->pBaseTypeDescription) + { + // ensure availability of base + type_info * base_rtti = getRTTI( + (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription ); + rtti = new __si_class_type_info( + strdup( rttiName ), (__class_type_info *)base_rtti ); + } + else + { + // this class has no base class + rtti = new __class_type_info( strdup( rttiName ) ); + } + + pair< t_rtti_map::iterator, bool > insertion( + m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) ); + OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" ); + } + else // taking already generated rtti + { + rtti = iFind->second; + } + } + } + else + { + rtti = iFind->second; + } + + return rtti; +} + +//-------------------------------------------------------------------------------------------------- +static void deleteException( void * pExc ) +{ + __cxa_exception const * header = ((__cxa_exception const *)pExc - 1); + typelib_TypeDescription * pTD = 0; + OUString unoName( toUNOname( header->exceptionType->name() ) ); + ::typelib_typedescription_getByName( &pTD, unoName.pData ); + OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" ); + if (pTD) + { + ::uno_destructData( pExc, pTD, cpp_release ); + ::typelib_typedescription_release( pTD ); + } +} + +//================================================================================================== +void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +{ + void * pCppExc; + type_info * rtti; + + { + // construct cpp exception object + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType ); + OSL_ASSERT( pTypeDescr ); + if (! pTypeDescr) + terminate(); + + pCppExc = __cxa_allocate_exception( pTypeDescr->nSize ); + ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); + + // destruct uno exception + ::uno_any_destruct( pUnoExc, 0 ); + // avoiding locked counts + static RTTI * s_rtti = 0; + if (! s_rtti) + { + MutexGuard guard( Mutex::getGlobalMutex() ); + if (! s_rtti) + { +#ifdef LEAK_STATIC_DATA + s_rtti = new RTTI(); +#else + static RTTI rtti_data; + s_rtti = &rtti_data; +#endif + } + } + rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr ); + TYPELIB_DANGER_RELEASE( pTypeDescr ); + OSL_ENSURE( rtti, "### no rtti for throwing exception!" ); + if (! rtti) + terminate(); + } + + __cxa_throw( pCppExc, rtti, deleteException ); +} + +//================================================================================================== +void fillUnoException( __cxa_exception * header, uno_Any * pExc, uno_Mapping * pCpp2Uno ) +{ + OSL_ENSURE( header, "### no exception header!!!" ); + if (! header) + terminate(); + + typelib_TypeDescription * pExcTypeDescr = 0; + OUString unoName( toUNOname( header->exceptionType->name() ) ); + ::typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData ); + OSL_ENSURE( pExcTypeDescr, "### can not get type description for exception!!!" ); + if (! pExcTypeDescr) + terminate(); + + // construct uno exception any + ::uno_any_constructAndConvert( pExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno ); + ::typelib_typedescription_release( pExcTypeDescr ); +} + +} + diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk b/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk new file mode 100644 index 000000000000..aadf2c312aef --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_s390/makefile.mk @@ -0,0 +1,112 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.2 $ +# +# last change: $Author: hr $ $Date: 2003-03-18 19:06:55 $ +# +# 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): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=bridges +TARGET=gcc3_uno +LIBTARGET=no +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCLINUX3gcc3" + +.IF "$(cppu_no_leak)" == "" +CFLAGS += -DLEAK_STATIC_DATA +.ENDIF + +CFLAGSNOOPT=-O0 + +SLOFILES= \ + $(SLO)$/except.obj \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj + +SHL1TARGET= $(TARGET) + +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB=i$(TARGET) +SHL1VERSIONMAP=..$/..$/bridge_exports.map + +SHL1OBJS= \ + $(SLO)$/except.obj \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) + +.ENDIF + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx b/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx new file mode 100644 index 000000000000..572e8d564243 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_s390/share.hxx @@ -0,0 +1,120 @@ +/************************************************************************* + * + * $RCSfile: share.hxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:55 $ + * + * 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_linux_s390/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx new file mode 100644 index 000000000000..cbb0c691df98 --- /dev/null +++ b/bridges/source/cpp_uno/gcc3_linux_s390/uno2cpp.cxx @@ -0,0 +1,653 @@ +/************************************************************************* + * + * $RCSfile: uno2cpp.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:06:56 $ + * + * 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 <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 sal_Int32 +invoke_count_words(char * pPT) +{ + sal_Int32 overflow = 0, gpr = 0, fpr = 0; + int c; // character of parameter type being decoded + + while (*pPT != 'X') { + c = *pPT; + switch (c) { + case 'D': /* type is double */ + if (fpr < 2) fpr++; else overflow+=2; + break; + + case 'F': /* type is float */ + if (fpr < 2) fpr++; else overflow++; + break; + + case 'H': /* type is long long */ + if (gpr < 4) gpr+=2; else gpr=5, overflow+=2; + break; + + case 'S': + case 'T': + case 'B': + case 'C': + if (gpr < 5) gpr++; else overflow++; + break; + + default: + if (gpr < 5) gpr++; else overflow++; + break; + } + pPT++; + } + /* Round up number of overflow words to ensure stack + stays aligned to 8 bytes. */ + return (overflow + 1) & ~1; +} + +static void +//invoke_copy_to_stack(sal_Int32 paramCount, sal_Int32 * pStackLongs, char * pPT, sal_Int32* d_ov, sal_Int32 overflow) +invoke_copy_to_stack(sal_Int32 * pStackLongs, char * pPT, sal_Int32* d_ov, sal_Int32 overflow) +{ + sal_Int32 *d_gpr = d_ov + overflow; + sal_Int64 *d_fpr = (sal_Int64 *)(d_gpr + 5); + sal_Int32 gpr = 0, fpr = 0; + char c; + + while (*pPT != 'X') { + c = *pPT; + switch (c) { + case 'D': /* type is double */ + if (fpr < 2) + *((double*) d_fpr) = *((double *)pStackLongs), d_fpr++, fpr++; + else + *((double*) d_ov ) = *((double *)pStackLongs), d_ov+=2; + + pStackLongs += 2; + break; + + case 'F': /* type is float */ + if (fpr < 2) { + *((sal_Int64*) d_fpr) = 0; + *((float*) d_fpr) = *((float *)pStackLongs), d_fpr++, fpr++; + } + else { + *((sal_Int64*) d_ov) = 0; + *((float*) d_ov ) = *((float *)pStackLongs), d_ov++; + } + + pStackLongs += 1; + break; + + case 'H': /* type is long long */ + if (gpr < 4) { + *((sal_Int64*) d_gpr) = *((sal_Int64*) pStackLongs), d_gpr+=2, gpr+=2; + } + else { + *((sal_Int64*) d_ov ) = *((sal_Int64*) pStackLongs), d_ov+=2, gpr=5; + } + pStackLongs += 2; + break; + + case 'S': + if (gpr < 5) + *((sal_uInt32*)d_gpr) = *((unsigned short*)pStackLongs), d_gpr++, gpr++; + else + *((sal_uInt32*)d_ov ) = *((unsigned short*)pStackLongs), d_ov++; + pStackLongs += 1; + break; + + case 'T': + if (gpr < 5) + *((sal_Int32*)d_gpr) = *((signed short*)pStackLongs), d_gpr++, gpr++; + else + *((sal_Int32*)d_ov ) = *((signed short*)pStackLongs), d_ov++; + pStackLongs += 1; + break; + + case 'B': + if (gpr < 5) + *((sal_uInt32*)d_gpr) = *((unsigned char*)pStackLongs), d_gpr++, gpr++; + else + *((sal_uInt32*)d_ov ) = *((unsigned char*)pStackLongs), d_ov++; + pStackLongs += 1; + break; + + case 'C': + if (gpr < 5) + *((sal_Int32*)d_gpr) = *((signed char*)pStackLongs), d_gpr++, gpr++; + else + *((sal_Int32*)d_ov ) = *((signed char*)pStackLongs), d_ov++; + pStackLongs += 1; + break; + + default: + if (gpr < 5) + *((sal_Int32*)d_gpr) = *pStackLongs, d_gpr++, gpr++; + else + *((sal_Int32*)d_ov ) = *pStackLongs, d_ov++; + pStackLongs += 1; + break; + } + pPT++; + } +} + +//================================================================================================== +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[5] as a storage area for + // the future values of registers r2 to r6 needed for the call, + // and similarly fpr[2] as a storage area for the future values + // of floating point registers f0 to f2 + + sal_Int32 *vtable = *(sal_Int32 **)pThis; +// sal_Int32 method = vtable[nVtableIndex + 2]; + sal_Int32 method = vtable[nVtableIndex]; + sal_Int32 overflow = invoke_count_words (pPT); + sal_Int32 result; + volatile double dret; // temporary function return values + volatile float fret; + volatile int iret, iret2; + + char * dummy = alloca(32); // dummy alloca to force r11 usage for exception handling + + __asm__ __volatile__ + ( + "lr 7,15\n\t" + "ahi 7,-48\n\t" + + "lr 3,%2\n\t" + "sll 3,2\n\t" + "lcr 3,3\n\t" + "l 2,0(15)\n\t" + "la 15,0(3,7)\n\t" + "st 2,0(15)\n\t" + + "lr 2,%0\n\t" + "lr 3,%1\n\t" + "la 4,96(15)\n\t" + "lr 5,%2\n\t" + "basr 14,%3\n\t" + + "ld 0,116(7)\n\t" + "ld 2,124(7)\n\t" + "lm 2,6,96(7)\n\t" + : + : "r" (pStackLongs), + "r" (pPT), + "r" (overflow), + "a" (invoke_copy_to_stack), + "a" (method), + "X" (dummy) + : "2", "3", "4", "5", "6", "7", "memory" + ); +// "basr 14,%8\n\t" + + (*(void (*)())method)(); + + __asm__ __volatile__ + ( + "la 15,48(7)\n\t" + + "lr %2,2\n\t" + "lr %3,3\n\t" + "ler %0,0\n\t" + "ldr %1,0\n\t" + + : "=f" (fret), "=f" (dret), "=r" (iret), "=r" (iret2) + ); + + switch( eReturnType ) + { + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: +// ((long*)pRegisterReturn)[0] = iret; + ((long*)pRegisterReturn)[1] = iret2; + 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 = fret; + 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++ = 'I'; //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: + *pPT++ = 'T'; + break; + case typelib_TypeClass_CHAR: + case typelib_TypeClass_UNSIGNED_SHORT: + *pPT++ = 'S'; + break; + case typelib_TypeClass_BOOLEAN: + *pPT++ = 'B'; + break; + case typelib_TypeClass_BYTE: + *pPT++ = 'C'; + 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 ); + } + // KBH: FIXME: is this the right way to pass these + *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 ); + } + } +} + +} + diff --git a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx index 9d4967906304..deabe8dc9955 100644 --- a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx +++ b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx @@ -2,9 +2,9 @@ * * $RCSfile: except.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: dbo $ $Date: 2001-08-01 10:09:58 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:57 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -166,7 +166,7 @@ public: inline __type_info( void * m_data, const char * m_d_name ) throw () : _m_data( m_data ) - { ::strcpy( _m_d_name, m_d_name ); } + { ::strcpy( _m_d_name, m_d_name ); } // #100211# - checked private: void * _m_data; diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java new file mode 100644 index 000000000000..c3d809c19b0e --- /dev/null +++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_info_holder.java @@ -0,0 +1,76 @@ +/************************************************************************* + * + * $RCSfile: JNI_info_holder.java,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:07:04 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +package com.sun.star.bridges.jni_uno; + +//================================================================================================== +public final class JNI_info_holder +{ + private static JNI_info_holder s_holder = new JNI_info_holder(); + + private static long s_jni_info_handle; + //______________________________________________________________________________________________ + private native void finalize( long jni_info_handle ); + //______________________________________________________________________________________________ + protected void finalize() + { + finalize( s_jni_info_handle ); + } +} diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java new file mode 100644 index 000000000000..2782eece91af --- /dev/null +++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/JNI_proxy.java @@ -0,0 +1,226 @@ +/************************************************************************* + * + * $RCSfile: JNI_proxy.java,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:07:04 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +package com.sun.star.bridges.jni_uno; + +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.IEnvironment; +import com.sun.star.uno.IQueryInterface; + + +//================================================================================================== +public final class JNI_proxy implements java.lang.reflect.InvocationHandler +{ + static { System.loadLibrary( "java_uno" ); } + protected static ClassLoader s_system_classloader = + ClassLoader.getSystemClassLoader(); + protected static Class s_InvocationHandler [] = + new Class [] { java.lang.reflect.InvocationHandler.class }; + + protected long m_bridge_handle; + protected IEnvironment m_java_env; + protected long m_receiver_handle; + protected long m_td_handle; + protected Type m_type; + protected String m_oid; + protected Class m_class; + + //______________________________________________________________________________________________ + public static String get_stack_trace( Throwable throwable ) + throws Throwable + { + boolean current_trace = false; + if (null == throwable) + { + throwable = new Throwable(); + current_trace = true; + } + java.io.StringWriter string_writer = new java.io.StringWriter(); + java.io.PrintWriter print_writer = new java.io.PrintWriter( string_writer, true ); + throwable.printStackTrace( print_writer ); + print_writer.flush(); + print_writer.close(); + string_writer.flush(); + String trace = string_writer.toString(); + if (current_trace) + { + // cut out first two lines + int n = trace.indexOf( '\n' ); + n = trace.indexOf( '\n', n +1 ); + trace = trace.substring( n +1 ); + } + return "\njava stack trace:\n" + trace; + } + + //______________________________________________________________________________________________ + private native void finalize( long bridge_handle ); + //______________________________________________________________________________________________ + public void finalize() + { + finalize( m_bridge_handle ); + } + //______________________________________________________________________________________________ + private JNI_proxy( + long bridge_handle, IEnvironment java_env, + long receiver_handle, long td_handle, Type type, String oid ) + { + m_bridge_handle = bridge_handle; + m_java_env = java_env; + m_receiver_handle = receiver_handle; + m_td_handle = td_handle; + m_type = type; + m_oid = oid; + m_class = m_type.getZClass(); + } + //______________________________________________________________________________________________ + public static Object create( + long bridge_handle, IEnvironment java_env, + long receiver_handle, long td_handle, Type type, String oid, + java.lang.reflect.Constructor proxy_ctor ) + throws Throwable + { + JNI_proxy handler = + new JNI_proxy( bridge_handle, java_env, receiver_handle, td_handle, type, oid ); + Object proxy = proxy_ctor.newInstance( new Object [] { handler } ); + return java_env.registerInterface( proxy, new String [] { oid }, type ); + } + //______________________________________________________________________________________________ + public static java.lang.reflect.Constructor get_proxy_ctor( Class clazz ) + throws Throwable + { + Class proxy_class = java.lang.reflect.Proxy.getProxyClass( + s_system_classloader, + new Class [] { clazz, IQueryInterface.class, com.sun.star.lib.uno.Proxy.class } ); + return proxy_class.getConstructor( s_InvocationHandler ); + } + + //______________________________________________________________________________________________ + private native Object dispatch_call( + long bridge_handle, String decl_class, String method, Object args [] ) + throws Throwable; + // InvocationHandler impl + //______________________________________________________________________________________________ + public Object invoke( + Object proxy, java.lang.reflect.Method method, Object args [] ) + throws Throwable + { + Class decl_class = method.getDeclaringClass(); + String method_name = method.getName(); + + if (Object.class.equals( decl_class )) + { + if (method_name.equals( "hashCode" )) // int hashCode() + { + return new Integer( System.identityHashCode( args[ 0 ] ) ); + } + else if (method_name.equals( "equals" )) // boolean equals( Object obj ) + { + return (proxy == args[ 0 ] ? Boolean.TRUE : Boolean.FALSE); + } + else if (method_name.equals( "toString" )) // String toString() + { + return this.toString() + " [oid=" + m_oid + ", type=" + m_type.getTypeName() + "]"; + } + } + // UNO interface call + else if (decl_class.isAssignableFrom( m_class )) + { + // dispatch interface call + return dispatch_call( m_bridge_handle, decl_class.getName(), method_name, args ); + } + // IQueryInterface impl + else if (IQueryInterface.class.equals( decl_class )) + { + if (method_name.equals( "queryInterface" )) // Object queryInterface( Type type ) + { + // opt + Object registered_proxy = + m_java_env.getRegisteredInterface( m_oid, (Type)args[ 0 ] ); + if (null == registered_proxy) + { + return dispatch_call( + m_bridge_handle, "com.sun.star.uno.XInterface", method_name, args ); + } + else + { + return registered_proxy; + } + } + else if (method_name.equals( "isSame" )) // boolean isSame( Object object ) + { + Object right = args[ 0 ]; + if (proxy == right) + return Boolean.TRUE; + if (m_oid.equals( UnoRuntime.generateOid( right ) )) + return Boolean.TRUE; + return Boolean.FALSE; + } + else if (method_name.equals( "getOid" )) // String getOid() + { + return m_oid; + } + } + + throw new com.sun.star.uno.RuntimeException( + "[jni_uno bridge error] unexpected call on proxy " + proxy.toString() + ": " + + method.toString() ); + } +} diff --git a/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk new file mode 100644 index 000000000000..2a2dc32811b6 --- /dev/null +++ b/bridges/source/jni_uno/java/com/sun/star/bridges/jni_uno/makefile.mk @@ -0,0 +1,86 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.2 $ +# +# last change: $Author: hr $ $Date: 2003-03-18 19:07:05 $ +# +# 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): _______________________________________ +# +# +# +#************************************************************************* +PRJ=..$/..$/..$/..$/..$/..$/..$/.. + +PRJNAME=bridges +TARGET=java_uno +PACKAGE=com$/sun$/star$/bridges$/jni_uno + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +JARFILES=jurt.jar sandbox.jar ridl.jar +JAVAFILES=$(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES))) + +JAVACLASSFILES= \ + $(CLASSDIR)$/$(PACKAGE)$/JNI_proxy.class \ + $(CLASSDIR)$/$(PACKAGE)$/JNI_info_holder.class + +JARCLASSDIRS=$(PACKAGE) +JARTARGET=$(TARGET).jar +JARCOMPRESS=TRUE + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/bridges/source/jni_uno/java_uno.map b/bridges/source/jni_uno/java_uno.map index e9e93c924cae..d6fc0aed44a9 100644 --- a/bridges/source/jni_uno/java_uno.map +++ b/bridges/source/jni_uno/java_uno.map @@ -1,11 +1,15 @@ -UDK_3_1_0 { +UDK_3_0_0 { global: uno_initEnvironment; uno_ext_getMapping; component_canUnload; - Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J; - Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call; - Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J; local: *; }; + +UDK_3.1 { + global: + Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J; + Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch_1call; + Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J; +} UDK_3_0_0; diff --git a/bridges/source/jni_uno/jni_base.h b/bridges/source/jni_uno/jni_base.h index c98101b4af15..65f26576c7ee 100644 --- a/bridges/source/jni_uno/jni_base.h +++ b/bridges/source/jni_uno/jni_base.h @@ -2,9 +2,9 @@ * * $RCSfile: jni_base.h,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 10:26:04 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -86,6 +86,7 @@ typedef __va_list va_list; namespace jni_uno { + class JNI_info; //================================================================================================== @@ -101,62 +102,6 @@ struct BridgeRuntimeError //################################################################################################## //================================================================================================== -struct rtl_mem -{ - inline static void * operator new ( size_t nSize ) - { return rtl_allocateMemory( nSize ); } - inline static void operator delete ( void * mem ) - { if (mem) rtl_freeMemory( mem ); } - inline static void * operator new ( size_t, void * mem ) - { return mem; } - inline static void operator delete ( void *, void * ) - {} - - static inline ::std::auto_ptr< rtl_mem > allocate( ::std::size_t bytes ); -}; -//-------------------------------------------------------------------------------------------------- -inline ::std::auto_ptr< rtl_mem > rtl_mem::allocate( ::std::size_t bytes ) -{ - void * p = rtl_allocateMemory( bytes ); - if (0 == p) - throw BridgeRuntimeError( OUSTR("out of memory!") ); - return ::std::auto_ptr< rtl_mem >( (rtl_mem *)p ); -} - -//################################################################################################## - -//================================================================================================== -class TypeDescr -{ - typelib_TypeDescription * m_td; - - TypeDescr( TypeDescr & ); // not impl - void operator = ( TypeDescr ); // not impl - -public: - inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref ); - inline ~TypeDescr() SAL_THROW( () ) - { TYPELIB_DANGER_RELEASE( m_td ); } - - inline typelib_TypeDescription * get() const - { return m_td; } -}; -//__________________________________________________________________________________________________ -inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref ) - : m_td( 0 ) -{ - TYPELIB_DANGER_GET( &m_td, td_ref ); - if (0 == m_td) - { - throw BridgeRuntimeError( - OUSTR("cannot get comprehensive type description for ") + - *reinterpret_cast< ::rtl::OUString const * >( &td_ref->pTypeName ) ); - } -} - -//################################################################################################## - -//================================================================================================== class JNI_context { JNI_info const * m_jni_info; @@ -165,7 +110,7 @@ class JNI_context JNI_context( JNI_context & ); // not impl void operator = ( JNI_context ); // not impl - void throw_bridge_error() const; + void java_exc_occured() const; public: inline explicit JNI_context( JNI_info const * jni_info, JNIEnv * env ) : m_jni_info( jni_info ), @@ -180,9 +125,30 @@ public: inline JNIEnv * get_jni_env() const { return m_env; } - inline void ensure_no_exception() const - { if (JNI_FALSE != m_env->ExceptionCheck()) throw_bridge_error(); } + inline void ensure_no_exception() const; // throws BridgeRuntimeError + inline bool assert_no_exception() const; // asserts and clears exception + + ::rtl::OUString get_stack_trace( jobject jo_exc = 0 ) const; }; +//__________________________________________________________________________________________________ +inline void JNI_context::ensure_no_exception() const +{ + if (JNI_FALSE != m_env->ExceptionCheck()) + { + java_exc_occured(); + } +} +//__________________________________________________________________________________________________ +inline bool JNI_context::assert_no_exception() const +{ + if (JNI_FALSE != m_env->ExceptionCheck()) + { + m_env->ExceptionClear(); + OSL_ENSURE( 0, "unexpected java exception occured!" ); + return false; + } + return true; +} //================================================================================================== class JNI_guarded_context @@ -193,17 +159,11 @@ class JNI_guarded_context void operator = ( JNI_guarded_context ); // not impl public: - JNI_guarded_context( + inline explicit JNI_guarded_context( JNI_info const * jni_info, ::jvmaccess::VirtualMachine * vm_access ) - // workaround this by catching internally CreationException -// try : AttachGuard( vm_access ), JNI_context( jni_info, AttachGuard::getEnvironment() ) {} -// catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &) -// { -// throw BridgeRuntimeError( OUSTR("attaching to java vm failed!") ); -// } }; //################################################################################################## @@ -281,6 +241,62 @@ inline JLocalAutoRef & JLocalAutoRef::operator = ( JLocalAutoRef & auto_ref ) return *this; } +//################################################################################################## + +//================================================================================================== +struct rtl_mem +{ + inline static void * operator new ( size_t nSize ) + { return rtl_allocateMemory( nSize ); } + inline static void operator delete ( void * mem ) + { if (mem) rtl_freeMemory( mem ); } + inline static void * operator new ( size_t, void * mem ) + { return mem; } + inline static void operator delete ( void *, void * ) + {} + + static inline ::std::auto_ptr< rtl_mem > allocate( ::std::size_t bytes ); +}; +//-------------------------------------------------------------------------------------------------- +inline ::std::auto_ptr< rtl_mem > rtl_mem::allocate( ::std::size_t bytes ) +{ + void * p = rtl_allocateMemory( bytes ); + if (0 == p) + throw BridgeRuntimeError( OUSTR("out of memory!") ); + return ::std::auto_ptr< rtl_mem >( (rtl_mem *)p ); +} + +//################################################################################################## + +//================================================================================================== +class TypeDescr +{ + typelib_TypeDescription * m_td; + + TypeDescr( TypeDescr & ); // not impl + void operator = ( TypeDescr ); // not impl + +public: + inline explicit TypeDescr( typelib_TypeDescriptionReference * td_ref ); + inline ~TypeDescr() SAL_THROW( () ) + { TYPELIB_DANGER_RELEASE( m_td ); } + + inline typelib_TypeDescription * get() const + { return m_td; } +}; +//__________________________________________________________________________________________________ +inline TypeDescr::TypeDescr( typelib_TypeDescriptionReference * td_ref ) + : m_td( 0 ) +{ + TYPELIB_DANGER_GET( &m_td, td_ref ); + if (0 == m_td) + { + throw BridgeRuntimeError( + OUSTR("cannot get comprehensive type description for ") + + *reinterpret_cast< ::rtl::OUString const * >( &td_ref->pTypeName ) ); + } +} + } #endif diff --git a/bridges/source/jni_uno/jni_bridge.cxx b/bridges/source/jni_uno/jni_bridge.cxx index b8dcc09b8247..e646610611de 100644 --- a/bridges/source/jni_uno/jni_bridge.cxx +++ b/bridges/source/jni_uno/jni_bridge.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_bridge.cxx,v $ * - * $Revision: 1.8 $ + * $Revision: 1.9 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 16:29:36 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:58 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -91,7 +91,7 @@ void SAL_CALL Mapping_release( uno_Mapping * mapping ) that->m_bridge->release(); } //-------------------------------------------------------------------------------------------------- -void SAL_CALL Mapping_java2uno( +void SAL_CALL Mapping_map_to_uno( uno_Mapping * mapping, void ** ppOut, void * pIn, typelib_InterfaceTypeDescription * td ) SAL_THROW_EXTERN_C() @@ -102,30 +102,38 @@ void SAL_CALL Mapping_java2uno( OSL_ASSERT( sizeof (void *) == sizeof (jobject) ); OSL_ENSURE( ppUnoI && td, "### null ptr!" ); - if (0 != *ppUnoI) + if (0 == javaI) { - uno_Interface * pUnoI = *(uno_Interface **)ppUnoI; - (*pUnoI->release)( pUnoI ); - *ppUnoI = 0; + if (0 != *ppUnoI) + { + uno_Interface * p = *(uno_Interface **)ppUnoI; + (*p->release)( p ); + *ppUnoI = 0; + } } - if (0 != javaI) + else { try { - Mapping const * that = static_cast< Mapping const * >( mapping ); - Bridge const * bridge = that->m_bridge; - + Bridge const * bridge = static_cast< Mapping const * >( mapping )->m_bridge; JNI_guarded_context jni( bridge->m_jni_info, reinterpret_cast< ::jvmaccess::VirtualMachine * >( bridge->m_java_env->pContext ) ); - JNI_type_info const * info = - bridge->m_jni_info->get_type_info( jni, (typelib_TypeDescription *)td ); - *ppUnoI = bridge->map_java2uno( jni, javaI, info ); + JNI_interface_type_info const * info = + static_cast< JNI_interface_type_info const * >( + bridge->m_jni_info->get_type_info( jni, (typelib_TypeDescription *)td ) ); + uno_Interface * pUnoI = bridge->map_to_uno( jni, javaI, info ); + if (0 != *ppUnoI) + { + uno_Interface * p = *(uno_Interface **)ppUnoI; + (*p->release)( p ); + } + *ppUnoI = pUnoI; } catch (BridgeRuntimeError & err) { -#ifdef _DEBUG +#if defined _DEBUG OString cstr_msg( OUStringToOString( OUSTR("[jni_uno bridge error] ") + err.m_message, RTL_TEXTENCODING_ASCII_US ) ); @@ -139,7 +147,7 @@ void SAL_CALL Mapping_java2uno( } } //-------------------------------------------------------------------------------------------------- -void SAL_CALL Mapping_uno2java( +void SAL_CALL Mapping_map_to_java( uno_Mapping * mapping, void ** ppOut, void * pIn, typelib_InterfaceTypeDescription * td ) SAL_THROW_EXTERN_C() @@ -152,30 +160,39 @@ void SAL_CALL Mapping_uno2java( try { - Mapping const * that = static_cast< Mapping const * >( mapping ); - Bridge const * bridge = that->m_bridge; - - JNI_guarded_context jni( - bridge->m_jni_info, - reinterpret_cast< ::jvmaccess::VirtualMachine * >( bridge->m_java_env->pContext ) ); - - if (0 != *ppJavaI) + if (0 == pUnoI) { - jni->DeleteGlobalRef( *ppJavaI ); - *ppJavaI = 0; + if (0 != *ppJavaI) + { + Bridge const * bridge = static_cast< Mapping const * >( mapping )->m_bridge; + JNI_guarded_context jni( + bridge->m_jni_info, + reinterpret_cast< ::jvmaccess::VirtualMachine * >( + bridge->m_java_env->pContext ) ); + jni->DeleteGlobalRef( *ppJavaI ); + *ppJavaI = 0; + } } - if (0 != pUnoI) + else { - JNI_type_info const * info = - bridge->m_jni_info->get_type_info( jni, (typelib_TypeDescription *)td ); - jobject jlocal = bridge->map_uno2java( jni, pUnoI, info ); + Bridge const * bridge = static_cast< Mapping const * >( mapping )->m_bridge; + JNI_guarded_context jni( + bridge->m_jni_info, + reinterpret_cast< ::jvmaccess::VirtualMachine * >( bridge->m_java_env->pContext ) ); + + JNI_interface_type_info const * info = + static_cast< JNI_interface_type_info const * >( + bridge->m_jni_info->get_type_info( jni, (typelib_TypeDescription *)td ) ); + jobject jlocal = bridge->map_to_java( jni, pUnoI, info ); + if (0 != *ppJavaI) + jni->DeleteGlobalRef( *ppJavaI ); *ppJavaI = jni->NewGlobalRef( jlocal ); jni->DeleteLocalRef( jlocal ); } } catch (BridgeRuntimeError & err) { -#ifdef _DEBUG +#if defined _DEBUG OString cstr_msg( OUStringToOString( OUSTR("[jni_uno bridge error] ") + err.m_message, RTL_TEXTENCODING_ASCII_US ) ); @@ -244,10 +261,10 @@ Bridge::Bridge( m_java_env( java_env ), m_registered_java2uno( registered_java2uno ) { - JNI_guarded_context jni( - 0 /* bootstrapping bridge, no jni_info available */, + // bootstrapping bridge jni_info + ::jvmaccess::VirtualMachine::AttachGuard jni( reinterpret_cast< ::jvmaccess::VirtualMachine * >( m_java_env->pContext ) ); - m_jni_info = JNI_info::get_jni_info( jni ); + m_jni_info = JNI_info::get_jni_info( jni.getEnvironment() ); OSL_ASSERT( 0 != m_java_env && 0 != m_uno_env ); (*((uno_Environment *)m_uno_env)->acquire)( (uno_Environment *)m_uno_env ); @@ -256,12 +273,12 @@ Bridge::Bridge( // java2uno m_java2uno.acquire = Mapping_acquire; m_java2uno.release = Mapping_release; - m_java2uno.mapInterface = Mapping_java2uno; + m_java2uno.mapInterface = Mapping_map_to_uno; m_java2uno.m_bridge = this; // uno2java m_uno2java.acquire = Mapping_acquire; m_uno2java.release = Mapping_release; - m_uno2java.mapInterface = Mapping_uno2java; + m_uno2java.mapInterface = Mapping_map_to_java; m_uno2java.m_bridge = this; (*g_moduleCount.modCnt.acquire)( &g_moduleCount.modCnt ); @@ -278,15 +295,17 @@ Bridge::~Bridge() SAL_THROW( () ) //################################################################################################## //__________________________________________________________________________________________________ -void JNI_context::throw_bridge_error() const +void JNI_context::java_exc_occured() const { + // !don't rely on JNI_info! + JLocalAutoRef jo_exc( *this, m_env->ExceptionOccurred() ); m_env->ExceptionClear(); OSL_ASSERT( jo_exc.is() ); if (! jo_exc.is()) { throw BridgeRuntimeError( - OUSTR("throw_bridge_error(): java exception occured, but not available!?") ); + OUSTR("java exception occured, but not available!?") + get_stack_trace() ); } // call toString(); don't rely on m_jni_info @@ -295,7 +314,7 @@ void JNI_context::throw_bridge_error() const { m_env->ExceptionClear(); throw BridgeRuntimeError( - OUSTR("essential java problem: cannot get class java.lang.Object!") ); + OUSTR("cannot get class java.lang.Object!") + get_stack_trace() ); } JLocalAutoRef jo_Object( *this, jo_class ); // method Object.toString() @@ -305,7 +324,7 @@ void JNI_context::throw_bridge_error() const { m_env->ExceptionClear(); throw BridgeRuntimeError( - OUSTR("essential java problem: cannot get method id of java.lang.Object.toString()!") ); + OUSTR("cannot get method id of java.lang.Object.toString()!") + get_stack_trace() ); } OSL_ASSERT( 0 != method_Object_toString ); @@ -315,10 +334,9 @@ void JNI_context::throw_bridge_error() const { m_env->ExceptionClear(); throw BridgeRuntimeError( - OUSTR("throw_bridge_error(): error examining exception object!") ); + OUSTR("error examining java exception object!") + get_stack_trace() ); } - OSL_ASSERT( sizeof (sal_Unicode) == sizeof (jchar) ); jsize len = m_env->GetStringLength( (jstring)jo_descr.get() ); auto_ptr< rtl_mem > ustr_mem( rtl_mem::allocate( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) ); @@ -328,13 +346,50 @@ void JNI_context::throw_bridge_error() const { m_env->ExceptionClear(); throw BridgeRuntimeError( - OUSTR("throw_bridge_error(): invalid string object!") ); + OUSTR("invalid java string object!") + get_stack_trace() ); } ustr->refCount = 1; ustr->length = len; ustr->buffer[ len ] = '\0'; + OUString message( (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE ); - throw BridgeRuntimeError( OUString( (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE ) ); + throw BridgeRuntimeError( message + get_stack_trace( jo_exc.get() ) ); +} +//__________________________________________________________________________________________________ +OUString JNI_context::get_stack_trace( jobject jo_exc ) const +{ + JLocalAutoRef jo_JNI_proxy( + *this, m_env->FindClass( "com/sun/star/bridges/jni_uno/JNI_proxy" ) ); + if (assert_no_exception()) + { + // static method JNI_proxy.get_stack_trace() + jmethodID method = m_env->GetStaticMethodID( + (jclass)jo_JNI_proxy.get(), "get_stack_trace", + "(Ljava/lang/Throwable;)Ljava/lang/String;" ); + if (assert_no_exception() && (0 != method)) + { + jvalue arg; + arg.l = jo_exc; + JLocalAutoRef jo_stack_trace( + *this, m_env->CallStaticObjectMethodA( (jclass)jo_JNI_proxy.get(), method, &arg ) ); + if (assert_no_exception()) + { + jsize len = m_env->GetStringLength( (jstring)jo_stack_trace.get() ); + auto_ptr< rtl_mem > ustr_mem( + rtl_mem::allocate( sizeof (rtl_uString) + (len * sizeof (sal_Unicode)) ) ); + rtl_uString * ustr = (rtl_uString *)ustr_mem.get(); + m_env->GetStringRegion( (jstring)jo_stack_trace.get(), 0, len, ustr->buffer ); + if (assert_no_exception()) + { + ustr->refCount = 1; + ustr->length = len; + ustr->buffer[ len ] = '\0'; + return OUString( (rtl_uString *)ustr_mem.release(), SAL_NO_ACQUIRE ); + } + } + } + } + return OUString(); } } @@ -373,7 +428,7 @@ void SAL_CALL uno_ext_getMapping( SAL_THROW_EXTERN_C() { OSL_ASSERT( 0 != ppMapping && 0 != pFrom && 0 != pTo ); - if (*ppMapping) + if (0 != *ppMapping) { (*(*ppMapping)->release)( *ppMapping ); *ppMapping = 0; @@ -428,7 +483,7 @@ void SAL_CALL uno_ext_getMapping( } catch (BridgeRuntimeError & err) { -#ifdef _DEBUG +#if defined _DEBUG OString cstr_msg( OUStringToOString( OUSTR("[jni_uno bridge error] ") + err.m_message, RTL_TEXTENCODING_ASCII_US ) ); diff --git a/bridges/source/jni_uno/jni_bridge.h b/bridges/source/jni_uno/jni_bridge.h index 4b16155b4968..b8235c18fd3f 100644 --- a/bridges/source/jni_uno/jni_bridge.h +++ b/bridges/source/jni_uno/jni_bridge.h @@ -2,9 +2,9 @@ * * $RCSfile: jni_bridge.h,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 16:29:36 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:59 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -122,13 +122,13 @@ struct Bridge void handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const; void call_java( - jobject javaI, JNI_type_info const * info, sal_Int32 function_pos, + jobject javaI, JNI_interface_type_info const * info, sal_Int32 function_pos, typelib_TypeDescriptionReference * return_type, typelib_MethodParameter * params, sal_Int32 nParams, void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const; - jobject map_uno2java( + jobject map_to_java( JNI_context const & jni, - uno_Interface * pUnoI, JNI_type_info const * info ) const; + uno_Interface * pUnoI, JNI_interface_type_info const * info ) const; // jni_java2uno.cxx void handle_java_exc( @@ -139,9 +139,9 @@ struct Bridge typelib_TypeDescriptionReference * return_tdref, sal_Int32 nParams, typelib_MethodParameter const * pParams, jobjectArray jo_args ) const; - uno_Interface * map_java2uno( + uno_Interface * map_to_uno( JNI_context const & jni, - jobject javaI, JNI_type_info const * info ) const; + jobject javaI, JNI_interface_type_info const * info ) const; }; } diff --git a/bridges/source/jni_uno/jni_data.cxx b/bridges/source/jni_uno/jni_data.cxx index 5471f445520c..5c8a108a7890 100644 --- a/bridges/source/jni_uno/jni_data.cxx +++ b/bridges/source/jni_uno/jni_data.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_data.cxx,v $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 10:26:04 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:59 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -257,6 +257,7 @@ void Bridge::map_to_uno( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } if (! assign) @@ -280,6 +281,7 @@ void Bridge::map_to_uno( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } @@ -293,6 +295,7 @@ void Bridge::map_to_uno( buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] incomplete type object: no type name!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } OUString type_name( jstring_to_oustring( jni, (jstring)jo_type_name.get() ) ); @@ -304,6 +307,7 @@ void Bridge::map_to_uno( buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") ); buf.append( type_name ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } typelib_typedescriptionreference_acquire( td.get()->pWeakRef ); @@ -315,7 +319,7 @@ void Bridge::map_to_uno( *(typelib_TypeDescriptionReference **)uno_data = td.get()->pWeakRef; break; } - case typelib_TypeClass_ANY: // xxx todo: possible opt on anys + case typelib_TypeClass_ANY: { JLocalAutoRef jo_out_holder( jni ); if (out_param) @@ -324,42 +328,22 @@ void Bridge::map_to_uno( jni.ensure_no_exception(); java_data.l = jo_out_holder.get(); } - if (0 == java_data.l) - { - OUStringBuffer buf( 128 ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); - buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") ); - throw BridgeRuntimeError( buf.makeStringAndClear() ); - } uno_Any * pAny = (uno_Any *)uno_data; - if (0 == java_data.l) // null-ref maps to empty any + if (0 == java_data.l) // null-ref maps to XInterface null-ref { if (assign) uno_any_destruct( pAny, 0 ); - uno_any_construct( pAny, 0, 0, 0 ); + uno_any_construct( pAny, 0, m_jni_info->m_XInterface_type_info->m_td.get(), 0 ); break; } - // dynamic type - JLocalAutoRef jo_class( - jni, jni->CallObjectMethodA( - java_data.l, m_jni_info->m_method_Object_getClass, 0 ) ); - jni.ensure_no_exception(); - jvalue arg; - arg.l = jo_class.get(); - bool is_any = - (JNI_FALSE != jni->CallBooleanMethodA( - m_jni_info->m_class_Any, m_jni_info->m_method_Object_equals, &arg )); - jni.ensure_no_exception(); - JLocalAutoRef jo_type( jni ); JLocalAutoRef jo_wrapped_holder( jni ); - if (is_any) + if (JNI_FALSE != jni->IsInstanceOf( java_data.l, m_jni_info->m_class_Any )) { - // wrapped value type + // boxed any jo_type.reset( jni->GetObjectField( java_data.l, m_jni_info->m_field_Any__type ) ); if (! jo_type.is()) { @@ -368,6 +352,7 @@ void Bridge::map_to_uno( buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] no type set at com.sun.star.uno.Any!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } // wrapped value @@ -377,19 +362,16 @@ void Bridge::map_to_uno( } else { - // check whether this is a proxy - if (JNI_FALSE != jni->IsAssignableFrom( - (jclass)jo_class.get(), m_jni_info->m_class_TypedProxy )) - { - // is proxy => determine exact type - jo_type.reset( jni->CallObjectMethodA( - java_data.l, m_jni_info->m_method_TypedProxy_getType, 0 ) ); - jni.ensure_no_exception(); - } - else - { - jo_type.reset( create_type( jni, (jclass)jo_class.get() ) ); - } + // create type out of class + JLocalAutoRef jo_class( jni, jni->GetObjectClass( java_data.l ) ); + jo_type.reset( create_type( jni, (jclass)jo_class.get() ) ); +#if defined DEBUG + JLocalAutoRef jo_toString( + jni, jni->CallObjectMethodA( + java_data.l, m_jni_info->m_method_Object_toString, 0 ) ); + jni.ensure_no_exception(); + OUString toString( jstring_to_oustring( jni, (jstring)jo_toString.get() ) ); +#endif } // get type name @@ -406,22 +388,15 @@ void Bridge::map_to_uno( buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] UNO type not found: ") ); buf.append( type_name ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } typelib_TypeClass type_class = value_td.get()->eTypeClass; - // just as fallback: should never happen - OSL_ENSURE( typelib_TypeClass_ANY != type_class, "forbidden nested any!" ); - if (typelib_TypeClass_ANY == type_class) - { - map_to_uno( - jni, uno_data, java_data, value_td.get()->pWeakRef, 0, - assign, false /* no out param */ ); - break; - } - if (assign) + { uno_any_destruct( pAny, 0 ); + } try { switch (type_class) @@ -430,45 +405,45 @@ void Bridge::map_to_uno( pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_CHAR: - pAny->pData = &pAny->pReserved; *(jchar *)&pAny->pReserved = jni->CallCharMethodA( java_data.l, m_jni_info->m_method_Character_charValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_BOOLEAN: - pAny->pData = &pAny->pReserved; *(jboolean *)&pAny->pReserved = jni->CallBooleanMethodA( java_data.l, m_jni_info->m_method_Boolean_booleanValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_BYTE: - pAny->pData = &pAny->pReserved; *(jbyte *)&pAny->pReserved = jni->CallByteMethodA( java_data.l, m_jni_info->m_method_Byte_byteValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT: - pAny->pData = &pAny->pReserved; *(jshort *)&pAny->pReserved = jni->CallShortMethodA( java_data.l, m_jni_info->m_method_Short_shortValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: - pAny->pData = &pAny->pReserved; *(jint *)&pAny->pReserved = jni->CallIntMethodA( java_data.l, m_jni_info->m_method_Integer_intValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: if (sizeof (sal_Int64) <= sizeof (void *)) { - pAny->pData = &pAny->pReserved; *(jlong *)&pAny->pReserved = jni->CallLongMethodA( java_data.l, m_jni_info->m_method_Long_longValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; } else { @@ -482,10 +457,10 @@ void Bridge::map_to_uno( case typelib_TypeClass_FLOAT: if (sizeof (float) <= sizeof (void *)) { - pAny->pData = &pAny->pReserved; *(jfloat *)&pAny->pReserved = jni->CallFloatMethodA( java_data.l, m_jni_info->m_method_Float_floatValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; } else { @@ -499,10 +474,10 @@ void Bridge::map_to_uno( case typelib_TypeClass_DOUBLE: if (sizeof (double) <= sizeof (void *)) { - pAny->pData = &pAny->pReserved; *(jdouble *)&pAny->pReserved = jni->CallDoubleMethodA( java_data.l, m_jni_info->m_method_Double_doubleValue, 0 ); jni.ensure_no_exception(); + pAny->pData = &pAny->pReserved; } else { @@ -513,21 +488,20 @@ void Bridge::map_to_uno( pAny->pData = mem.release(); } break; - case typelib_TypeClass_STRING: // anies often contain strings; copy string directly - pAny->pData = &pAny->pReserved; + case typelib_TypeClass_STRING: // opt: anies often contain strings; copy string directly pAny->pReserved = 0; jstring_to_ustring( jni, (rtl_uString **)&pAny->pReserved, (jstring)java_data.l ); + pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_TYPE: case typelib_TypeClass_ENUM: case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_INTERFACE: - pAny->pData = &pAny->pReserved; - pAny->pReserved = 0; map_to_uno( jni, &pAny->pReserved, java_data, value_td.get()->pWeakRef, 0, false /* no assign */, false /* no out param */ ); + pAny->pData = &pAny->pReserved; break; case typelib_TypeClass_STRUCT: case typelib_TypeClass_EXCEPTION: @@ -545,6 +519,7 @@ void Bridge::map_to_uno( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); buf.append( type_name ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported value type of any!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } } @@ -552,7 +527,10 @@ void Bridge::map_to_uno( catch (...) { if (assign) - uno_any_construct( pAny, 0, 0, 0 ); // restore some valid any + { + // restore to valid any + uno_any_construct( pAny, 0, 0, 0 ); + } throw; } typelib_typedescriptionreference_acquire( value_td.get()->pWeakRef ); @@ -574,6 +552,7 @@ void Bridge::map_to_uno( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } @@ -597,16 +576,17 @@ void Bridge::map_to_uno( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } if (0 == info) - { - TypeDescr td( type ); - info = m_jni_info->get_type_info( jni, td.get() ); - } + info = m_jni_info->get_type_info( jni, type ); + JNI_compound_type_info const * comp_info = + static_cast< JNI_compound_type_info const * >( info ); + typelib_CompoundTypeDescription * comp_td = - (typelib_CompoundTypeDescription *)info->m_td.get(); + (typelib_CompoundTypeDescription *)comp_info->m_td.get(); sal_Int32 nPos = 0; sal_Int32 nMembers = comp_td->nMembers; @@ -617,7 +597,7 @@ void Bridge::map_to_uno( map_to_uno( jni, uno_data, java_data, ((typelib_TypeDescription *)comp_td->pBaseTypeDescription)->pWeakRef, - info->m_base, + comp_info->m_base, assign, false /* no out param */ ); } @@ -625,7 +605,7 @@ void Bridge::map_to_uno( { void * p = (char *)uno_data + comp_td->pMemberOffsets[ nPos ]; typelib_TypeDescriptionReference * member_type = comp_td->ppTypeRefs[ nPos ]; - jfieldID field_id = info->m_fields[ nPos ]; + jfieldID field_id = comp_info->m_fields[ nPos ]; switch (member_type->eTypeClass) { case typelib_TypeClass_CHAR: @@ -661,15 +641,21 @@ void Bridge::map_to_uno( if (0 == field_id) // special for Message: call Throwable.getMessage() { OSL_ASSERT( - typelib_typedescriptionreference_equals( + type_equals( type, m_jni_info->m_Exception_type.getTypeLibType() ) || - typelib_typedescriptionreference_equals( + type_equals( type, m_jni_info->m_RuntimeException_type.getTypeLibType() ) ); OSL_ASSERT( 0 == nPos ); // first member // call getMessage() jo_field.reset( jni->CallObjectMethodA( java_data.l, m_jni_info->m_method_Throwable_getMessage, 0 ) ); + jni.ensure_no_exception(); + if (! jo_field.is()) // message may be null + { + jo_field.reset( jni->NewStringUTF( "" ) ); + jni.ensure_no_exception(); + } } else { @@ -720,6 +706,7 @@ void Bridge::map_to_uno( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] null-ref given!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } @@ -852,6 +839,7 @@ void Bridge::map_to_uno( buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported sequence element type: ") ); buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } } @@ -875,20 +863,19 @@ void Bridge::map_to_uno( { if (assign) { - uno_Interface * pUnoI = *(uno_Interface **)uno_data; - if (0 != pUnoI) - (*pUnoI->release)( pUnoI ); + uno_Interface * p = *(uno_Interface **)uno_data; + if (0 != p) + (*p->release)( p ); } *(uno_Interface **)uno_data = 0; } else { if (0 == info) - { - TypeDescr td( type ); - info = m_jni_info->get_type_info( jni, td.get() ); - } - uno_Interface * pUnoI = map_java2uno( jni, java_data.l, info ); + info = m_jni_info->get_type_info( jni, type ); + JNI_interface_type_info const * iface_info = + static_cast< JNI_interface_type_info const * >( info ); + uno_Interface * pUnoI = map_to_uno( jni, java_data.l, iface_info ); if (assign) { uno_Interface * p = *(uno_Interface **)uno_data; @@ -905,6 +892,7 @@ void Bridge::map_to_uno( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_uno():") ); buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } } @@ -1267,8 +1255,8 @@ void Bridge::map_to_java( JLocalAutoRef jo_in( jni ); if (in_param) { - jo_in.reset( create_type( - jni, *(typelib_TypeDescriptionReference * const *)uno_data ) ); + jo_in.reset( + create_type( jni, *(typelib_TypeDescriptionReference * const *)uno_data ) ); } if (0 == java_data->l) { @@ -1286,8 +1274,8 @@ void Bridge::map_to_java( else { OSL_ASSERT( in_param ); - java_data->l = create_type( - jni, *(typelib_TypeDescriptionReference * const *)uno_data ); + java_data->l = + create_type( jni, *(typelib_TypeDescriptionReference * const *)uno_data ); } break; } @@ -1297,24 +1285,122 @@ void Bridge::map_to_java( if (in_param) { uno_Any const * pAny = (uno_Any const *)uno_data; - if (typelib_TypeClass_VOID != pAny->pType->eTypeClass) + +#if defined BRIDGES_JNI_UNO_FORCE_BOXED_ANY + if (typelib_TypeClass_VOID == pAny->pType->eTypeClass) + { + jo_any.reset( jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) ); + } + else { jvalue args[ 2 ]; - // map value map_to_java( - jni, args, pAny->pData, pAny->pType, 0, + jni, &args[ 1 ], pAny->pData, pAny->pType, 0, true /* in */, false /* no out */, true /* create integral wrappers */ ); - switch (pAny->pType->eTypeClass) + jo_any.reset( args[ 1 ].l ); + // build up com.sun.star.uno.Any + JLocalAutoRef jo_type( jni, create_type( jni, pAny->pType ) ); + args[ 0 ].l = jo_type.get(); + jo_any.reset( + jni->NewObjectA( + m_jni_info->m_class_Any, + m_jni_info->m_ctor_Any_with_Type_Object, args ) ); + jni.ensure_no_exception(); + } +#else + switch (pAny->pType->eTypeClass) + { + case typelib_TypeClass_VOID: + jo_any.reset( jni->NewLocalRef( m_jni_info->m_object_Any_VOID ) ); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + { + jvalue args[ 2 ]; + args[ 0 ].s = *(jshort const *)&pAny->pReserved; + JLocalAutoRef jo_val( + jni, jni->NewObjectA( + m_jni_info->m_class_Short, m_jni_info->m_ctor_Short_with_short, args ) ); + jni.ensure_no_exception(); + // box up in com.sun.star.uno.Any + args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_SHORT; + args[ 1 ].l = jo_val.get(); + jo_any.reset( + jni->NewObjectA( + m_jni_info->m_class_Any, + m_jni_info->m_ctor_Any_with_Type_Object, args ) ); + jni.ensure_no_exception(); + break; + } + case typelib_TypeClass_UNSIGNED_LONG: + { + jvalue args[ 2 ]; + args[ 0 ].i = *(jint const *)&pAny->pReserved; + JLocalAutoRef jo_val( + jni, jni->NewObjectA( + m_jni_info->m_class_Integer, m_jni_info->m_ctor_Integer_with_int, args ) ); + jni.ensure_no_exception(); + // box up in com.sun.star.uno.Any + args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_LONG; + args[ 1 ].l = jo_val.get(); + jo_any.reset( + jni->NewObjectA( + m_jni_info->m_class_Any, + m_jni_info->m_ctor_Any_with_Type_Object, args ) ); + jni.ensure_no_exception(); + break; + } + case typelib_TypeClass_UNSIGNED_HYPER: + { + jvalue args[ 2 ]; + args[ 0 ].j = *(jlong const *)pAny->pData; + JLocalAutoRef jo_val( + jni, jni->NewObjectA( + m_jni_info->m_class_Long, m_jni_info->m_ctor_Long_with_long, args ) ); + jni.ensure_no_exception(); + // box up in com.sun.star.uno.Any + args[ 0 ].l = m_jni_info->m_object_Type_UNSIGNED_HYPER; + args[ 1 ].l = jo_val.get(); + jo_any.reset( + jni->NewObjectA( + m_jni_info->m_class_Any, + m_jni_info->m_ctor_Any_with_Type_Object, args ) ); + jni.ensure_no_exception(); + break; + } + case typelib_TypeClass_STRING: // opt strings + jo_any.reset( ustring_to_jstring( jni, (rtl_uString *)pAny->pReserved ) ); + break; + case typelib_TypeClass_SEQUENCE: + { + jvalue java_data; + // prefetch sequence td + TypeDescr seq_td( pAny->pType ); + map_to_java( + jni, &java_data, pAny->pData, seq_td.get()->pWeakRef, 0, + true /* in */, false /* no out */, true /* create integral wrappers */ ); + jo_any.reset( java_data.l ); + + // determine inner element type + ::com::sun::star::uno::Type element_type( + ((typelib_IndirectTypeDescription *)seq_td.get())->pType ); + while (typelib_TypeClass_SEQUENCE == element_type.getTypeLibType()->eTypeClass) + { + TypeDescr element_td( element_type.getTypeLibType() ); + typelib_typedescriptionreference_assign( + reinterpret_cast< typelib_TypeDescriptionReference ** >( &element_type ), + ((typelib_IndirectTypeDescription *)element_td.get())->pType ); + } + // box up only if unsigned element type + switch (element_type.getTypeLibType()->eTypeClass) { case typelib_TypeClass_UNSIGNED_SHORT: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_UNSIGNED_HYPER: { - // build up com.sun.star.uno.Any - JLocalAutoRef jo_val( jni, args[ 0 ].l ); - JLocalAutoRef jo_type( jni, create_type( jni, pAny->pType ) ); + jvalue args[ 2 ]; + JLocalAutoRef jo_type( jni, create_type( jni, seq_td.get()->pWeakRef ) ); args[ 0 ].l = jo_type.get(); - args[ 1 ].l = jo_val.get(); + args[ 1 ].l = jo_any.get(); jo_any.reset( jni->NewObjectA( m_jni_info->m_class_Any, @@ -1322,12 +1408,55 @@ void Bridge::map_to_java( jni.ensure_no_exception(); break; } - default: - jo_any.reset( args[ 0 ].l ); - break; } + break; + } + case typelib_TypeClass_INTERFACE: + { + uno_Interface * pUnoI = (uno_Interface *)pAny->pReserved; + if (is_XInterface( pAny->pType )) + { + if (0 != pUnoI) + { + jo_any.reset( + map_to_java( jni, pUnoI, m_jni_info->m_XInterface_type_info ) ); + } + // else: empty XInterface ref maps to null-ref + } + else + { + JNI_interface_type_info const * iface_info = + static_cast< JNI_interface_type_info const * >( + m_jni_info->get_type_info( jni, pAny->pType ) ); + if (0 != pUnoI) + { + jo_any.reset( map_to_java( jni, pUnoI, iface_info ) ); + } + // box up in com.sun.star.uno.Any + jvalue args[ 2 ]; + args[ 0 ].l = iface_info->m_type; + args[ 1 ].l = jo_any.get(); + jo_any.reset( + jni->NewObjectA( + m_jni_info->m_class_Any, + m_jni_info->m_ctor_Any_with_Type_Object, args ) ); + jni.ensure_no_exception(); + } + break; + } + default: + { + jvalue java_data; + map_to_java( + jni, &java_data, pAny->pData, pAny->pType, 0, + true /* in */, false /* no out */, true /* create integral wrappers */ ); + jo_any.reset( java_data.l ); + break; } + } +#endif } + if (out_param) { if (0 == java_data->l) @@ -1401,10 +1530,9 @@ void Bridge::map_to_java( case typelib_TypeClass_EXCEPTION: { if (0 == info) - { - TypeDescr td( type ); - info = m_jni_info->get_type_info( jni, td.get() ); - } + info = m_jni_info->get_type_info( jni, type ); + JNI_compound_type_info const * comp_info = + static_cast< JNI_compound_type_info const * >( info ); JLocalAutoRef jo_comp( jni ); if (in_param) @@ -1415,16 +1543,18 @@ void Bridge::map_to_java( jni, ustring_to_jstring( jni, *(rtl_uString **)uno_data ) ); jvalue arg; arg.l = jo_message.get(); - jo_comp.reset( jni->NewObjectA( info->m_class, info->m_ctor, &arg ) ); + jo_comp.reset( jni->NewObjectA( comp_info->m_class, comp_info->m_exc_ctor, &arg ) ); jni.ensure_no_exception(); } else { - jo_comp.reset( jni->NewObjectA( info->m_class, info->m_ctor, 0 ) ); + jo_comp.reset( jni->AllocObject( comp_info->m_class ) ); jni.ensure_no_exception(); } - for ( JNI_type_info const * linfo = info; 0 != linfo; linfo = linfo->m_base ) + for ( JNI_compound_type_info const * linfo = comp_info; + 0 != linfo; + linfo = static_cast< JNI_compound_type_info const * >( linfo->m_base ) ) { typelib_CompoundTypeDescription * comp_td = (typelib_CompoundTypeDescription *)linfo->m_td.get(); @@ -1500,7 +1630,7 @@ void Bridge::map_to_java( { if (0 == java_data->l) { - java_data->l = jni->NewObjectArray( 1, info->m_class, jo_comp.get() ); + java_data->l = jni->NewObjectArray( 1, comp_info->m_class, jo_comp.get() ); jni.ensure_no_exception(); } else @@ -1719,9 +1849,7 @@ void Bridge::map_to_java( case typelib_TypeClass_STRUCT: case typelib_TypeClass_EXCEPTION: { - TypeDescr element_td( element_type ); - JNI_type_info const * element_info = - m_jni_info->get_type_info( jni, element_td.get() ); + JNI_type_info const * element_info = m_jni_info->get_type_info( jni, element_type ); jo_ar.reset( jni->NewObjectArray( nElements, element_info->m_class, 0 ) ); jni.ensure_no_exception(); @@ -1729,7 +1857,7 @@ void Bridge::map_to_java( if (0 < nElements) { char * p = (char *)seq->elements; - sal_Int32 nSize = element_td.get()->nSize; + sal_Int32 nSize = element_info->m_td.get()->nSize; for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) { jvalue val; @@ -1747,7 +1875,7 @@ void Bridge::map_to_java( case typelib_TypeClass_SEQUENCE: { OStringBuffer buf( 64 ); - m_jni_info->append_sig( &buf, element_type ); + JNI_info::append_sig( &buf, element_type, false /* use class XInterface */ ); OString class_name( buf.makeStringAndClear() ); JLocalAutoRef jo_seq_class( jni, find_class( jni, class_name.getStr() ) ); @@ -1774,27 +1902,26 @@ void Bridge::map_to_java( } case typelib_TypeClass_INTERFACE: { - TypeDescr element_td( element_type ); - JNI_type_info const * element_info = - m_jni_info->get_type_info( jni, element_td.get() ); + JNI_interface_type_info const * iface_info = + static_cast< JNI_interface_type_info const * >( + m_jni_info->get_type_info( jni, element_type ) ); - jo_ar.reset( jni->NewObjectArray( nElements, element_info->m_class, 0 ) ); + jo_ar.reset( jni->NewObjectArray( nElements, iface_info->m_class, 0 ) ); jni.ensure_no_exception(); if (0 < nElements) { - char * p = (char *)seq->elements; - sal_Int32 nSize = element_td.get()->nSize; + uno_Interface ** pp = (uno_Interface **)seq->elements; for ( sal_Int32 nPos = 0; nPos < nElements; ++nPos ) { - jvalue val; - map_to_java( - jni, &val, p + (nSize * nPos), element_type, element_info, - true /* in */, false /* no out */ ); - JLocalAutoRef jo_element( jni, val.l ); - jni->SetObjectArrayElement( - (jobjectArray)jo_ar.get(), nPos, jo_element.get() ); - jni.ensure_no_exception(); + uno_Interface * pUnoI = pp[ nPos ]; + if (0 != pUnoI) + { + JLocalAutoRef jo_element( jni, map_to_java( jni, pUnoI, iface_info ) ); + jni->SetObjectArrayElement( + (jobjectArray)jo_ar.get(), nPos, jo_element.get() ); + jni.ensure_no_exception(); + } } } break; @@ -1806,6 +1933,7 @@ void Bridge::map_to_java( buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported element type: ") ); buf.append( *reinterpret_cast< OUString const * >( &element_type->pTypeName ) ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } } @@ -1814,7 +1942,7 @@ void Bridge::map_to_java( { if (0 == java_data->l) { - JLocalAutoRef jo_element_class( jni, get_class( jni, jo_ar.get() ) ); + JLocalAutoRef jo_element_class( jni, jni->GetObjectClass( jo_ar.get() ) ); if (in_param) { java_data->l = @@ -1849,39 +1977,20 @@ void Bridge::map_to_java( if (0 != pUnoI) { if (0 == info) - { - TypeDescr td( type ); - info = m_jni_info->get_type_info( jni, td.get() ); - } - jo_iface.reset( map_uno2java( jni, pUnoI, info ) ); + info = m_jni_info->get_type_info( jni, type ); + JNI_interface_type_info const * iface_info = + static_cast< JNI_interface_type_info const * >( info ); + jo_iface.reset( map_to_java( jni, pUnoI, iface_info ) ); } } if (out_param) { if (0 == java_data->l) { - if (typelib_typedescriptionreference_equals( - type, m_jni_info->m_XInterface_td.get()->pWeakRef )) - { - java_data->l = jni->NewObjectArray( - 1, m_jni_info->m_class_Object, jo_iface.get() ); - jni.ensure_no_exception(); - } - else - { - OUString const & type_name = - *reinterpret_cast< OUString const * >( &type->pTypeName ); - OString class_name( - OUStringToOString( - type_name.replace( '.', '/' ), - RTL_TEXTENCODING_ASCII_US ) ); - JLocalAutoRef jo_iface_class( - jni, find_class( jni, class_name.getStr() ) ); - - java_data->l = jni->NewObjectArray( - 1, (jclass)jo_iface_class.get(), jo_iface.get() ); - jni.ensure_no_exception(); - } + if (0 == info) + info = m_jni_info->get_type_info( jni, type ); + java_data->l = jni->NewObjectArray( 1, info->m_class, jo_iface.get() ); + jni.ensure_no_exception(); } else { @@ -1902,6 +2011,7 @@ void Bridge::map_to_java( buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("[map_to_java():") ); buf.append( *reinterpret_cast< OUString const * >( &type->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] unsupported type!") ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } } diff --git a/bridges/source/jni_uno/jni_helper.h b/bridges/source/jni_uno/jni_helper.h index 1238f59b81b6..63e091b30790 100644 --- a/bridges/source/jni_uno/jni_helper.h +++ b/bridges/source/jni_uno/jni_helper.h @@ -2,9 +2,9 @@ * * $RCSfile: jni_helper.h,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 10:26:04 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:59 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -116,30 +116,6 @@ inline jclass find_class( JNI_context const & jni, char const * class_name ) jni.ensure_no_exception(); return jo_class; } -//-------------------------------------------------------------------------------------------------- -inline jclass find_class( JNI_context const & jni, ::rtl::OUString const & class_name ) -{ - ::rtl::OString cstr_name( ::rtl::OUStringToOString( class_name, RTL_TEXTENCODING_ASCII_US ) ); - return find_class( jni, cstr_name ); -} -//-------------------------------------------------------------------------------------------------- -inline jclass get_class( JNI_context const & jni, jobject jo ) -{ - jclass jo_class = (jclass)jni->CallObjectMethodA( - jo, jni.get_info()->m_method_Object_getClass, 0 ); - jni.ensure_no_exception(); - return jo_class; -} -//-------------------------------------------------------------------------------------------------- -inline ::rtl::OUString get_class_name( JNI_context const & jni, jobject jo ) -{ - JLocalAutoRef jo_class( jni, get_class( jni, jo ) ); - JLocalAutoRef jo_name( - jni, jni->CallObjectMethodA( - jo_class.get(), jni.get_info()->m_method_Class_getName, 0 ) ); - jni.ensure_no_exception(); - return jstring_to_oustring( jni, (jstring)jo_name.get() ); -} //################################################################################################## diff --git a/bridges/source/jni_uno/jni_info.cxx b/bridges/source/jni_uno/jni_info.cxx index 9b47ee8ed632..e0bd540087c8 100644 --- a/bridges/source/jni_uno/jni_info.cxx +++ b/bridges/source/jni_uno/jni_info.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_info.cxx,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 16:29:37 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:06:59 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -68,6 +68,7 @@ #include "uno/lbnames.h" +namespace css = ::com::sun::star; using namespace ::std; using namespace ::osl; using namespace ::rtl; @@ -77,40 +78,71 @@ namespace jni_uno //__________________________________________________________________________________________________ JNI_type_info::JNI_type_info( - JNI_context const & jni, typelib_InterfaceTypeDescription * td ) - : m_td( (typelib_TypeDescription *)td ), - m_methods( 0 ), - m_fields( 0 ) + JNI_context const & jni, ::com::sun::star::uno::TypeDescription const & td ) + : m_base( 0 ), + m_td( td ), + m_class( 0 ) { m_td.makeComplete(); if (! m_td.get()->bComplete) { - throw BridgeRuntimeError( - OUSTR("cannot make type incomplete: ") + - *reinterpret_cast< OUString const * >( &m_td.get()->pTypeName ) ); + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot make type incomplete: ") ); + buf.append( *reinterpret_cast< OUString const * >( &m_td.get()->pTypeName ) ); + buf.append( jni.get_stack_trace() ); + throw BridgeRuntimeError( buf.makeStringAndClear() ); } - td = (typelib_InterfaceTypeDescription *)m_td.get(); +} + +//################################################################################################## + +//__________________________________________________________________________________________________ +void JNI_interface_type_info::destroy( JNIEnv * jni_env ) +{ + JNI_type_info::destruct( jni_env ); + jni_env->DeleteGlobalRef( m_proxy_ctor ); + jni_env->DeleteGlobalRef( m_type ); + delete [] m_methods; + delete this; +} +//__________________________________________________________________________________________________ +JNI_interface_type_info::JNI_interface_type_info( + JNI_context const & jni, css::uno::TypeDescription const & td_ ) + : JNI_type_info( jni, td_ ) +{ + OSL_ASSERT( typelib_TypeClass_INTERFACE == m_td.get()->eTypeClass ); + typelib_InterfaceTypeDescription * td = (typelib_InterfaceTypeDescription *)m_td.get(); OUString const & uno_name = *reinterpret_cast< OUString const * >( &((typelib_TypeDescription *)td)->pTypeName ); - OString java_name( - OUStringToOString( uno_name.replace( '.', '/' ), RTL_TEXTENCODING_ASCII_US ) ); - JLocalAutoRef jo_class( jni, find_class( jni, java_name.getStr() ) ); - JNI_info const * jni_info = jni.get_info(); // retrieve info for base type typelib_TypeDescription * base_td = (typelib_TypeDescription *)td->pBaseTypeDescription; m_base = (0 == base_td ? 0 : jni_info->get_type_info( jni, base_td )); - // if ! XInterface - if (! typelib_typedescriptionreference_equals( - ((typelib_TypeDescription *)td)->pWeakRef, jni_info->m_XInterface_td.get()->pWeakRef )) + OString java_name( + OUStringToOString( uno_name.replace( '.', '/' ), RTL_TEXTENCODING_ASCII_US ) ); + JLocalAutoRef jo_class( jni, find_class( jni, java_name.getStr() ) ); + JLocalAutoRef jo_type( jni, create_type( jni, (jclass)jo_class.get() ) ); + + // get proxy ctor + jvalue arg; + arg.l = jo_class.get(); + JLocalAutoRef jo_proxy_ctor( + jni, jni->CallStaticObjectMethodA( + jni_info->m_class_JNI_proxy, jni_info->m_method_JNI_proxy_get_proxy_ctor, &arg ) ); + + if (is_XInterface( m_td.get()->pWeakRef )) + { + m_methods = 0; // no methods + } + else { + // retrieve method ids for all direct members try { - // retrieve method ids for all direct members m_methods = new jmethodID[ td->nMapFunctionIndexToMemberIndex ]; sal_Int32 nMethodIndex = 0; typelib_TypeDescriptionReference ** ppMembers = td->ppMembers; @@ -133,10 +165,10 @@ JNI_type_info::JNI_type_info( typelib_MethodParameter const & param = method_td->pParams[ nPos ]; if (param.bOut) sig_buf.append( '[' ); - jni_info->append_sig( &sig_buf, param.pTypeRef ); + JNI_info::append_sig( &sig_buf, param.pTypeRef ); } sig_buf.append( ')' ); - jni_info->append_sig( &sig_buf, method_td->pReturnTypeRef ); + JNI_info::append_sig( &sig_buf, method_td->pReturnTypeRef ); OString method_signature( sig_buf.makeStringAndClear() ); OString method_name( @@ -158,7 +190,7 @@ JNI_type_info::JNI_type_info( (typelib_InterfaceAttributeTypeDescription *)member_td.get(); // type sig - jni_info->append_sig( &sig_buf, attribute_td->pAttributeTypeRef ); + JNI_info::append_sig( &sig_buf, attribute_td->pAttributeTypeRef ); OString type_sig( sig_buf.makeStringAndClear() ); sig_buf.ensureCapacity( 64 ); // member name @@ -192,7 +224,7 @@ JNI_type_info::JNI_type_info( name_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("set") ); name_buf.append( member_name ); method_name = OUStringToOString( - name_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ); + name_buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ); m_methods[ nMethodIndex ] = jni->GetMethodID( (jclass)jo_class.get(), method_name.getStr(), method_signature.getStr() ); @@ -209,27 +241,30 @@ JNI_type_info::JNI_type_info( throw; } } + m_class = (jclass)jni->NewGlobalRef( jo_class.get() ); + m_type = jni->NewGlobalRef( jo_type.get() ); + m_proxy_ctor = jni->NewGlobalRef( jo_proxy_ctor.get() ); +} - JLocalAutoRef jo_type( jni, create_type( jni, (jclass)jo_class.get() ) ); +//################################################################################################## - m_class = (jclass)jni->NewGlobalRef( jo_class.get() ); - m_jo_type = jni->NewGlobalRef( jo_type.get() ); +//__________________________________________________________________________________________________ +void JNI_compound_type_info::destroy( JNIEnv * jni_env ) +{ + JNI_type_info::destruct( jni_env ); + delete [] m_fields; + delete this; } //__________________________________________________________________________________________________ -JNI_type_info::JNI_type_info( - JNI_context const & jni, typelib_CompoundTypeDescription * td ) - : m_td( (typelib_TypeDescription *)td ), - m_methods( 0 ), - m_fields( 0 ) +JNI_compound_type_info::JNI_compound_type_info( + JNI_context const & jni, css::uno::TypeDescription const & td_ ) + : JNI_type_info( jni, td_ ), + m_fields( 0 ), + m_exc_ctor( 0 ) { - m_td.makeComplete(); - if (! m_td.get()->bComplete) - { - throw BridgeRuntimeError( - OUSTR("cannot make type incomplete: ") + - *reinterpret_cast< OUString const * >( &m_td.get()->pTypeName ) ); - } - td = (typelib_CompoundTypeDescription *)m_td.get(); + OSL_ASSERT( typelib_TypeClass_STRUCT == m_td.get()->eTypeClass || + typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass ); + typelib_CompoundTypeDescription * td = (typelib_CompoundTypeDescription *)m_td.get(); OUString const & uno_name = *reinterpret_cast< OUString const * >( &((typelib_TypeDescription *)td)->pTypeName ); @@ -240,12 +275,13 @@ JNI_type_info::JNI_type_info( JNI_info const * jni_info = jni.get_info(); - // retrieve ctor - m_ctor = jni->GetMethodID( - (jclass)jo_class.get(), "<init>", - (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass ? "(Ljava/lang/String;)V" : "()V") ); - jni.ensure_no_exception(); - OSL_ASSERT( 0 != m_ctor ); + if (typelib_TypeClass_EXCEPTION == m_td.get()->eTypeClass) + { + // retrieve exc ctor( msg ) + m_exc_ctor = jni->GetMethodID( (jclass)jo_class.get(), "<init>", "(Ljava/lang/String;)V" ); + jni.ensure_no_exception(); + OSL_ASSERT( 0 != m_exc_ctor ); + } // retrieve info for base type typelib_TypeDescription * base_td = (typelib_TypeDescription *)td->pBaseTypeDescription; @@ -253,10 +289,10 @@ JNI_type_info::JNI_type_info( try { - if (typelib_typedescriptionreference_equals( + if (type_equals( ((typelib_TypeDescription *)td)->pWeakRef, jni_info->m_Exception_type.getTypeLibType() ) || - typelib_typedescriptionreference_equals( + type_equals( ((typelib_TypeDescription *)td)->pWeakRef, jni_info->m_RuntimeException_type.getTypeLibType() )) { @@ -277,7 +313,7 @@ JNI_type_info::JNI_type_info( for ( sal_Int32 nPos = 0; nPos < nMembers; ++nPos ) { OStringBuffer sig_buf( 32 ); - jni_info->append_sig( &sig_buf, td->ppTypeRefs[ nPos ] ); + JNI_info::append_sig( &sig_buf, td->ppTypeRefs[ nPos ] ); OString sig( sig_buf.makeStringAndClear() ); OString member_name( @@ -299,64 +335,99 @@ JNI_type_info::JNI_type_info( } m_class = (jclass)jni->NewGlobalRef( jo_class.get() ); - m_jo_type = 0; } + +//################################################################################################## + //__________________________________________________________________________________________________ -void JNI_type_info::destroy( JNI_context const & jni ) +JNI_type_info const * JNI_info::create_type_info( + JNI_context const & jni, typelib_TypeDescription * td ) const { - delete [] m_fields; - delete [] m_methods; - jni->DeleteGlobalRef( m_class ); - delete this; -} + OUString const & uno_name = *reinterpret_cast< OUString const * >( &td->pTypeName ); -//################################################################################################## + JNI_type_info * new_info; + switch (td->eTypeClass) + { + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + new_info = new JNI_compound_type_info( + jni, *reinterpret_cast< css::uno::TypeDescription const * >( &td ) ); + break; + case typelib_TypeClass_INTERFACE: + new_info = new JNI_interface_type_info( + jni, *reinterpret_cast< css::uno::TypeDescription const * >( &td ) ); + break; + default: + { + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("type info not supported for ") ); + buf.append( uno_name ); + buf.append( jni.get_stack_trace() ); + throw BridgeRuntimeError( buf.makeStringAndClear() ); + } + } + // look up + JNI_type_info * info; + ClearableMutexGuard guard( m_mutex ); + JNI_type_info_holder & holder = m_type_map[ uno_name ]; + if (0 == holder.m_info) // new insertion + { + holder.m_info = new_info; + guard.clear(); + info = new_info; + } + else // inserted in the meantime + { + info = holder.m_info; + guard.clear(); + new_info->destroy( jni.get_jni_env() ); + } + return info; +} //__________________________________________________________________________________________________ JNI_type_info const * JNI_info::get_type_info( JNI_context const & jni, typelib_TypeDescription * td ) const { - JNI_type_info * info; + if (is_XInterface( td->pWeakRef )) + { + return m_XInterface_type_info; + } OUString const & uno_name = *reinterpret_cast< OUString const * >( &td->pTypeName ); - + JNI_type_info const * info; ClearableMutexGuard guard( m_mutex ); t_str2type::const_iterator iFind( m_type_map.find( uno_name ) ); if (m_type_map.end() == iFind) { guard.clear(); + info = create_type_info( jni, td ); + } + else + { + info = iFind->second.m_info; + } - JNI_type_info * new_info; - switch (td->eTypeClass) - { - case typelib_TypeClass_STRUCT: - case typelib_TypeClass_EXCEPTION: - new_info = new JNI_type_info( jni, (typelib_CompoundTypeDescription *)td ); - break; - case typelib_TypeClass_INTERFACE: - new_info = new JNI_type_info( jni, (typelib_InterfaceTypeDescription *)td ); - break; - default: - throw BridgeRuntimeError( - OUSTR("unsupported: type info for ") + - *reinterpret_cast< OUString const * >( &td->pTypeName ) ); - } + return info; +} +//__________________________________________________________________________________________________ +JNI_type_info const * JNI_info::get_type_info( + JNI_context const & jni, typelib_TypeDescriptionReference * type ) const +{ + if (is_XInterface( type )) + { + return m_XInterface_type_info; + } - // look again - ClearableMutexGuard guard( m_mutex ); - JNI_type_info_holder & holder = m_type_map[ uno_name ]; - if (0 == holder.m_info) // new insertion - { - holder.m_info = new_info; - guard.clear(); - info = new_info; - } - else // inserted in the meantime - { - info = holder.m_info; - guard.clear(); - new_info->destroy( jni ); - } + OUString const & uno_name = *reinterpret_cast< OUString const * >( &type->pTypeName ); + JNI_type_info const * info; + ClearableMutexGuard guard( m_mutex ); + t_str2type::const_iterator iFind( m_type_map.find( uno_name ) ); + if (m_type_map.end() == iFind) + { + guard.clear(); + TypeDescr td( type ); + info = create_type_info( jni, td.get() ); } else { @@ -369,47 +440,27 @@ JNI_type_info const * JNI_info::get_type_info( JNI_type_info const * JNI_info::get_type_info( JNI_context const & jni, OUString const & uno_name ) const { - JNI_type_info * info; + if (uno_name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") )) + { + return m_XInterface_type_info; + } + JNI_type_info const * info; ClearableMutexGuard guard( m_mutex ); t_str2type::const_iterator iFind( m_type_map.find( uno_name ) ); if (m_type_map.end() == iFind) { guard.clear(); - - ::com::sun::star::uno::TypeDescription td( uno_name ); + css::uno::TypeDescription td( uno_name ); if (! td.is()) - throw BridgeRuntimeError( OUSTR("UNO type not found: ") + uno_name ); - - JNI_type_info * new_info; - switch (td.get()->eTypeClass) - { - case typelib_TypeClass_STRUCT: - case typelib_TypeClass_EXCEPTION: - new_info = new JNI_type_info( jni, (typelib_CompoundTypeDescription *)td.get() ); - break; - case typelib_TypeClass_INTERFACE: - new_info = new JNI_type_info( jni, (typelib_InterfaceTypeDescription *)td.get() ); - break; - default: - throw BridgeRuntimeError( OUSTR("unsupported: type info for ") + uno_name ); - } - - // look again - ClearableMutexGuard guard( m_mutex ); - JNI_type_info_holder & holder = m_type_map[ uno_name ]; - if (0 == holder.m_info) // new insertion - { - holder.m_info = new_info; - guard.clear(); - info = new_info; - } - else // inserted in the meantime { - info = holder.m_info; - guard.clear(); - new_info->destroy( jni ); + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("UNO type not found: ") ); + buf.append( uno_name ); + buf.append( jni.get_stack_trace() ); + throw BridgeRuntimeError( buf.makeStringAndClear() ); } + info = create_type_info( jni, td.get() ); } else { @@ -418,22 +469,20 @@ JNI_type_info const * JNI_info::get_type_info( return info; } + //__________________________________________________________________________________________________ -JNI_info::JNI_info( JNI_context const & jni ) - : m_XInterface_td( - ::getCppuType( - (::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > const *)0 ) ), - m_XInterface_queryInterface_td( - ((typelib_InterfaceTypeDescription *)m_XInterface_td.get())->ppMembers[ 0 ] ), - m_Exception_type( - ::getCppuType( - (::com::sun::star::uno::Exception const *)0 ) ), - m_RuntimeException_type( - ::getCppuType( - (::com::sun::star::uno::RuntimeException const *)0 ) ), - m_class_JNI_proxy( 0 ) +JNI_info::JNI_info( JNIEnv * jni_env ) + : m_XInterface_queryInterface_td( + ((typelib_InterfaceTypeDescription *)css::uno::TypeDescription( + ::getCppuType( + (css::uno::Reference< css::uno::XInterface > const *)0 ) ).get())->ppMembers[ 0 ] ), + m_Exception_type( ::getCppuType( (css::uno::Exception const *)0 ) ), + m_RuntimeException_type( ::getCppuType( (css::uno::RuntimeException const *)0 ) ), + m_void_type( ::getCppuVoidType() ), + m_class_JNI_proxy( 0 ), + m_XInterface_type_info( 0 ) { - // !!!no JNI_info available at JNI_context!!! + JNI_context jni( this, jni_env ); // !no proper jni_info! // class lookup JLocalAutoRef jo_Object( @@ -474,27 +523,14 @@ JNI_info::JNI_info( JNI_context const & jni ) jni, find_class( jni, "com/sun/star/uno/TypeClass" ) ); JLocalAutoRef jo_IEnvironment( jni, find_class( jni, "com/sun/star/uno/IEnvironment" ) ); - JLocalAutoRef jo_TypedProxy( - jni, find_class( jni, "com/sun/star/lib/uno/TypedProxy" ) ); JLocalAutoRef jo_JNI_proxy( jni, find_class( jni, "com/sun/star/bridges/jni_uno/JNI_proxy" ) ); - // method Object.getClass() - m_method_Object_getClass = jni->GetMethodID( - (jclass)jo_Object.get(), "getClass", "()Ljava/lang/Class;" ); - jni.ensure_no_exception(); - OSL_ASSERT( 0 != m_method_Object_getClass ); - // method Object.equals() - m_method_Object_equals = jni->GetMethodID( - (jclass)jo_Object.get(), "equals", "(Ljava/lang/Object;)Z" ); - jni.ensure_no_exception(); - OSL_ASSERT( 0 != m_method_Object_equals ); // method Object.toString() m_method_Object_toString = jni->GetMethodID( (jclass)jo_Object.get(), "toString", "()Ljava/lang/String;" ); jni.ensure_no_exception(); OSL_ASSERT( 0 != m_method_Object_toString ); - // method Class.getName() m_method_Class_getName = jni->GetMethodID( (jclass)jo_Class.get(), "getName", "()Ljava/lang/String;" ); @@ -658,24 +694,17 @@ JNI_info::JNI_info( JNI_context const & jni ) "(Ljava/lang/Object;[Ljava/lang/String;Lcom/sun/star/uno/Type;)Ljava/lang/Object;" ); jni.ensure_no_exception(); OSL_ASSERT( 0 != m_method_IEnvironment_registerInterface ); - // method IEnvironment.revokeInterface() - m_method_IEnvironment_revokeInterface = jni->GetMethodID( - (jclass)jo_IEnvironment.get(), "revokeInterface", - "(Ljava/lang/String;Lcom/sun/star/uno/Type;)V" ); - jni.ensure_no_exception(); - OSL_ASSERT( 0 != m_method_IEnvironment_revokeInterface ); - // method TypedProxy.getType() - m_method_TypedProxy_getType = jni->GetMethodID( - (jclass)jo_TypedProxy.get(), "getType", - "()Lcom/sun/star/uno/Type;" ); + // static method JNI_proxy.get_proxy_ctor() + m_method_JNI_proxy_get_proxy_ctor = jni->GetStaticMethodID( + (jclass)jo_JNI_proxy.get(), "get_proxy_ctor", + "(Ljava/lang/Class;)Ljava/lang/reflect/Constructor;" ); jni.ensure_no_exception(); - OSL_ASSERT( 0 != m_method_TypedProxy_getType ); - + OSL_ASSERT( 0 != m_method_JNI_proxy_get_proxy_ctor ); // static method JNI_proxy.create() m_method_JNI_proxy_create = jni->GetStaticMethodID( (jclass)jo_JNI_proxy.get(), "create", - "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang/String;)Ljava/lang/Object;" ); + "(JLcom/sun/star/uno/IEnvironment;JJLcom/sun/star/uno/Type;Ljava/lang/String;Ljava/lang/reflect/Constructor;)Ljava/lang/Object;" ); jni.ensure_no_exception(); OSL_ASSERT( 0 != m_method_JNI_proxy_create ); // field JNI_proxy.m_receiver_handle @@ -714,13 +743,41 @@ JNI_info::JNI_info( JNI_context const & jni ) jni, jni->CallStaticObjectMethodA( (jclass)jo_UnoRuntime.get(), method_getEnvironment, args ) ); + // get com.sun.star.uno.Any.VOID + jfieldID field_Any_VOID = jni->GetStaticFieldID( + (jclass)jo_Any.get(), "VOID", "Lcom/sun/star/uno/Any;" ); + jni.ensure_no_exception(); + OSL_ASSERT( 0 != field_Any_VOID ); + JLocalAutoRef jo_Any_VOID( + jni, jni->GetStaticObjectField( (jclass)jo_Any.get(), field_Any_VOID ) ); + // get com.sun.star.uno.Type.UNSIGNED_SHORT + jfieldID field_Type_UNSIGNED_SHORT = jni->GetStaticFieldID( + (jclass)jo_Type.get(), "UNSIGNED_SHORT", "Lcom/sun/star/uno/Type;" ); + jni.ensure_no_exception(); + OSL_ASSERT( 0 != field_Type_UNSIGNED_SHORT ); + JLocalAutoRef jo_Type_UNSIGNED_SHORT( + jni, jni->GetStaticObjectField( (jclass)jo_Type.get(), field_Type_UNSIGNED_SHORT ) ); + // get com.sun.star.uno.Type.UNSIGNED_LONG + jfieldID field_Type_UNSIGNED_LONG = jni->GetStaticFieldID( + (jclass)jo_Type.get(), "UNSIGNED_LONG", "Lcom/sun/star/uno/Type;" ); + jni.ensure_no_exception(); + OSL_ASSERT( 0 != field_Type_UNSIGNED_LONG ); + JLocalAutoRef jo_Type_UNSIGNED_LONG( + jni, jni->GetStaticObjectField( (jclass)jo_Type.get(), field_Type_UNSIGNED_LONG ) ); + // get com.sun.star.uno.Type.UNSIGNED_HYPER + jfieldID field_Type_UNSIGNED_HYPER = jni->GetStaticFieldID( + (jclass)jo_Type.get(), "UNSIGNED_HYPER", "Lcom/sun/star/uno/Type;" ); + jni.ensure_no_exception(); + OSL_ASSERT( 0 != field_Type_UNSIGNED_HYPER ); + JLocalAutoRef jo_Type_UNSIGNED_HYPER( + jni, jni->GetStaticObjectField( (jclass)jo_Type.get(), field_Type_UNSIGNED_HYPER ) ); + // make global refs m_class_UnoRuntime = (jclass)jni->NewGlobalRef( jo_UnoRuntime.get() ); m_class_RuntimeException = (jclass)jni->NewGlobalRef( jo_RuntimeException.get() ); m_class_Any = (jclass)jni->NewGlobalRef( jo_Any.get() ); m_class_Type = (jclass)jni->NewGlobalRef( jo_Type.get() ); m_class_TypeClass = (jclass)jni->NewGlobalRef( jo_TypeClass.get() ); - m_class_TypedProxy = (jclass)jni->NewGlobalRef( jo_TypedProxy.get() ); m_class_JNI_proxy = (jclass)jni->NewGlobalRef( jo_JNI_proxy.get() ); m_class_Character = (jclass)jni->NewGlobalRef( jo_Character.get() ); @@ -734,46 +791,69 @@ JNI_info::JNI_info( JNI_context const & jni ) m_class_String = (jclass)jni->NewGlobalRef( jo_String.get() ); m_class_Object = (jclass)jni->NewGlobalRef( jo_Object.get() ); + m_object_Any_VOID = jni->NewGlobalRef( jo_Any_VOID.get() ); + m_object_Type_UNSIGNED_SHORT = jni->NewGlobalRef( jo_Type_UNSIGNED_SHORT.get() ); + m_object_Type_UNSIGNED_LONG = jni->NewGlobalRef( jo_Type_UNSIGNED_LONG.get() ); + m_object_Type_UNSIGNED_HYPER = jni->NewGlobalRef( jo_Type_UNSIGNED_HYPER.get() ); m_object_java_env = jni->NewGlobalRef( jo_java_env.get() ); + + try + { + css::uno::TypeDescription XInterface_td( + ::getCppuType( (css::uno::Reference< css::uno::XInterface > const *)0 ) ); + m_XInterface_type_info = new JNI_interface_type_info( jni, XInterface_td ); + } + catch (...) + { + destruct( jni_env ); + throw; + } } //__________________________________________________________________________________________________ -void JNI_info::destroy( JNI_context const & jni ) +void JNI_info::destruct( JNIEnv * jni_env ) { t_str2type::const_iterator iPos( m_type_map.begin() ); t_str2type::const_iterator const iEnd( m_type_map.begin() ); for ( ; iPos != iEnd; ++iPos ) { - iPos->second.m_info->destroy( jni ); + iPos->second.m_info->destroy( jni_env ); + } + if (0 != m_XInterface_type_info) + { + const_cast< JNI_interface_type_info * >( m_XInterface_type_info )->destroy( jni_env ); } // free global refs - jni->DeleteGlobalRef( m_object_java_env ); - - jni->DeleteGlobalRef( m_class_Object ); - jni->DeleteGlobalRef( m_class_String ); - jni->DeleteGlobalRef( m_class_Double ); - jni->DeleteGlobalRef( m_class_Float ); - jni->DeleteGlobalRef( m_class_Long ); - jni->DeleteGlobalRef( m_class_Integer ); - jni->DeleteGlobalRef( m_class_Short ); - jni->DeleteGlobalRef( m_class_Byte ); - jni->DeleteGlobalRef( m_class_Boolean ); - jni->DeleteGlobalRef( m_class_Character ); - - jni->DeleteGlobalRef( m_class_JNI_proxy ); - jni->DeleteGlobalRef( m_class_RuntimeException ); - jni->DeleteGlobalRef( m_class_UnoRuntime ); - jni->DeleteGlobalRef( m_class_TypeClass ); - jni->DeleteGlobalRef( m_class_Type ); - jni->DeleteGlobalRef( m_class_Any ); - - delete this; + jni_env->DeleteGlobalRef( m_object_java_env ); + jni_env->DeleteGlobalRef( m_object_Any_VOID ); + jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_SHORT ); + jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_LONG ); + jni_env->DeleteGlobalRef( m_object_Type_UNSIGNED_HYPER ); + + jni_env->DeleteGlobalRef( m_class_Object ); + jni_env->DeleteGlobalRef( m_class_String ); + jni_env->DeleteGlobalRef( m_class_Double ); + jni_env->DeleteGlobalRef( m_class_Float ); + jni_env->DeleteGlobalRef( m_class_Long ); + jni_env->DeleteGlobalRef( m_class_Integer ); + jni_env->DeleteGlobalRef( m_class_Short ); + jni_env->DeleteGlobalRef( m_class_Byte ); + jni_env->DeleteGlobalRef( m_class_Boolean ); + jni_env->DeleteGlobalRef( m_class_Character ); + + jni_env->DeleteGlobalRef( m_class_JNI_proxy ); + jni_env->DeleteGlobalRef( m_class_RuntimeException ); + jni_env->DeleteGlobalRef( m_class_UnoRuntime ); + jni_env->DeleteGlobalRef( m_class_TypeClass ); + jni_env->DeleteGlobalRef( m_class_Type ); + jni_env->DeleteGlobalRef( m_class_Any ); } //__________________________________________________________________________________________________ -JNI_info const * JNI_info::get_jni_info( JNI_context const & jni ) +JNI_info const * JNI_info::get_jni_info( JNIEnv * jni_env ) { // !!!no JNI_info available at JNI_context!!! + JNI_context jni( 0, jni_env ); JLocalAutoRef jo_JNI_info_holder( jni, find_class( jni, "com/sun/star/bridges/jni_uno/JNI_info_holder" ) ); @@ -786,25 +866,26 @@ JNI_info const * JNI_info::get_jni_info( JNI_context const & jni ) JNI_info const * jni_info = reinterpret_cast< JNI_info const * >( jni->GetStaticLongField( (jclass)jo_JNI_info_holder.get(), field_s_jni_info_handle ) ); - if (0 == jni_info) // UNinitialized? + if (0 == jni_info) // un-initialized? { - JNI_info * new_info = new JNI_info( jni ); + JNI_info * new_info = new JNI_info( jni_env ); ClearableMutexGuard guard( Mutex::getGlobalMutex() ); jni_info = reinterpret_cast< JNI_info const * >( jni->GetStaticLongField( (jclass)jo_JNI_info_holder.get(), field_s_jni_info_handle ) ); - if (0 == jni_info) // still UNinitialized? + if (0 == jni_info) // still un-initialized? { - jni->SetStaticLongField( (jclass)jo_JNI_info_holder.get(), field_s_jni_info_handle, + jni->SetStaticLongField( + (jclass)jo_JNI_info_holder.get(), field_s_jni_info_handle, reinterpret_cast< jlong >( new_info ) ); jni_info = new_info; } else { guard.clear(); - new_info->destroy( jni ); + new_info->destroy( jni_env ); } } @@ -815,10 +896,9 @@ JNI_info const * JNI_info::get_jni_info( JNI_context const & jni ) //################################################################################################## JNIEXPORT void JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1info_1holder_finalize__J( - JNIEnv * jni_env, jobject jo_proxy, jlong jni_info_handle ) + JNIEnv * jni_env, jobject jo_holder, jlong jni_info_handle ) SAL_THROW_EXTERN_C() { ::jni_uno::JNI_info * jni_info = reinterpret_cast< ::jni_uno::JNI_info * >( jni_info_handle ); - ::jni_uno::JNI_context jni( jni_info, jni_env ); - jni_info->destroy( jni ); + jni_info->destroy( jni_env ); } diff --git a/bridges/source/jni_uno/jni_info.h b/bridges/source/jni_uno/jni_info.h index 93ee448d63ce..52497cc9b3c3 100644 --- a/bridges/source/jni_uno/jni_info.h +++ b/bridges/source/jni_uno/jni_info.h @@ -2,9 +2,9 @@ * * $RCSfile: jni_info.h,v $ * - * $Revision: 1.5 $ + * $Revision: 1.6 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 16:29:37 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:00 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -78,31 +78,67 @@ namespace jni_uno { +//-------------------------------------------------------------------------------------------------- +inline bool type_equals( + typelib_TypeDescriptionReference * type1, typelib_TypeDescriptionReference * type2 ) +{ + return ((type1 == type2) || + ((type1->eTypeClass == type2->eTypeClass) && + reinterpret_cast< ::rtl::OUString const * >( &type1->pTypeName )->equals( + *reinterpret_cast< ::rtl::OUString const * >( &type2->pTypeName ) ))); +} +//-------------------------------------------------------------------------------------------------- +inline bool is_XInterface( typelib_TypeDescriptionReference * type ) +{ + return ((typelib_TypeClass_INTERFACE == type->eTypeClass) && + reinterpret_cast< ::rtl::OUString const * >( &type->pTypeName )->equalsAsciiL( + RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") )); +} + //================================================================================================== struct JNI_type_info { + JNI_type_info const * m_base; ::com::sun::star::uno::TypeDescription m_td; jclass m_class; - JNI_type_info const * m_base; - jobject m_jo_type; // is unused (0) for compound types + + virtual void destroy( JNIEnv * jni_env ) = 0; +protected: + inline void destruct( JNIEnv * jni_env ) + { jni_env->DeleteGlobalRef( m_class ); } + inline ~JNI_type_info() {} + JNI_type_info( + JNI_context const & jni, ::com::sun::star::uno::TypeDescription const & td ); +}; +//================================================================================================== +struct JNI_interface_type_info : public JNI_type_info +{ + jobject m_proxy_ctor; // proxy ctor + jobject m_type; // sorted via typelib function index jmethodID * m_methods; + + virtual void destroy( JNIEnv * jni_env ); + JNI_interface_type_info( + JNI_context const & jni, ::com::sun::star::uno::TypeDescription const & td ); +}; +//================================================================================================== +struct JNI_compound_type_info : public JNI_type_info +{ + jmethodID m_exc_ctor; // ctor( msg ) for exceptions // sorted via typelib member index jfieldID * m_fields; - jmethodID m_ctor; - - JNI_type_info( JNI_context const & jni, typelib_InterfaceTypeDescription * td ); - JNI_type_info( JNI_context const & jni, typelib_CompoundTypeDescription * td ); - void destroy( JNI_context const & jni ); -private: - inline ~JNI_type_info() {} + virtual void destroy( JNIEnv * jni_env ); + JNI_compound_type_info( + JNI_context const & jni, ::com::sun::star::uno::TypeDescription const & td ); }; + //================================================================================================== struct JNI_type_info_holder { JNI_type_info * m_info; - inline JNI_type_info_holder() SAL_THROW( () ) + inline JNI_type_info_holder() : m_info( 0 ) {} }; @@ -115,20 +151,13 @@ class JNI_info mutable ::osl::Mutex m_mutex; mutable t_str2type m_type_map; - // - jmethodID m_method_IEnvironment_getRegisteredInterface; - jmethodID m_method_IEnvironment_registerInterface; - jmethodID m_method_IEnvironment_revokeInterface; - public: // jobject m_object_java_env; - - // - ::com::sun::star::uno::TypeDescription m_XInterface_td; - ::com::sun::star::uno::TypeDescription m_XInterface_queryInterface_td; - ::com::sun::star::uno::Type const & m_Exception_type; - ::com::sun::star::uno::Type const & m_RuntimeException_type; + jobject m_object_Any_VOID; + jobject m_object_Type_UNSIGNED_SHORT; + jobject m_object_Type_UNSIGNED_LONG; + jobject m_object_Type_UNSIGNED_HYPER; // jclass m_class_Object; @@ -147,12 +176,9 @@ public: jclass m_class_Any; jclass m_class_Type; jclass m_class_TypeClass; - jclass m_class_TypedProxy; jclass m_class_JNI_proxy; // - jmethodID m_method_Object_getClass; - jmethodID m_method_Object_equals; jmethodID m_method_Object_toString; jmethodID m_method_Class_getName; jmethodID m_method_Throwable_getMessage; @@ -173,6 +199,9 @@ public: jmethodID m_method_Long_longValue; jmethodID m_method_Short_shortValue; + // + jmethodID m_method_IEnvironment_getRegisteredInterface; + jmethodID m_method_IEnvironment_registerInterface; jmethodID m_method_UnoRuntime_generateOid; jmethodID m_method_UnoRuntime_queryInterface; jmethodID m_ctor_Any_with_Type_Object; @@ -183,8 +212,9 @@ public: jfieldID m_field_Type__typeName; jmethodID m_method_TypeClass_fromInt; jfieldID m_field_Enum_m_value; - jmethodID m_method_TypedProxy_getType; + // + jmethodID m_method_JNI_proxy_get_proxy_ctor; jmethodID m_method_JNI_proxy_create; jfieldID m_field_JNI_proxy_m_receiver_handle; jfieldID m_field_JNI_proxy_m_td_handle; @@ -192,31 +222,48 @@ public: jfieldID m_field_JNI_proxy_m_oid; // + ::com::sun::star::uno::TypeDescription m_XInterface_queryInterface_td; + ::com::sun::star::uno::Type const & m_Exception_type; + ::com::sun::star::uno::Type const & m_RuntimeException_type; + ::com::sun::star::uno::Type const & m_void_type; + // + JNI_interface_type_info const * m_XInterface_type_info; + + // JNI_type_info const * get_type_info( - JNI_context const & jni, typelib_TypeDescription * td ) const; + JNI_context const & jni, typelib_TypeDescription * type ) const; + JNI_type_info const * get_type_info( + JNI_context const & jni, typelib_TypeDescriptionReference * type ) const; JNI_type_info const * get_type_info( JNI_context const & jni, ::rtl::OUString const & uno_name ) const; // - inline void append_sig( - ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type ) const; - // - inline jobject java_env_getRegisteredInterface( - JNI_context const & jni, jstring oid, jobject type ) const; - inline jobject java_env_registerInterface( - JNI_context const & jni, jobject javaI, jstring oid, jobject type ) const; - inline void java_env_revokeInterface( - JNI_context const & jni, jstring oid, jobject type ) const; + inline static void append_sig( + ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type, + bool use_Object_for_type_XInterface = true ); + + // get this + static JNI_info const * get_jni_info( JNIEnv * jni_env ); + inline void destroy( JNIEnv * jni_env ); - // - static JNI_info const * get_jni_info( JNI_context const & jni ); - void destroy( JNI_context const & jni ); private: - JNI_info( JNI_context const & jni ); + JNI_type_info const * create_type_info( + JNI_context const & jni, typelib_TypeDescription * td ) const; + + void destruct( JNIEnv * jni_env ); + + JNI_info( JNIEnv * jni_env ); inline ~JNI_info() {} }; //__________________________________________________________________________________________________ +inline void JNI_info::destroy( JNIEnv * jni_env ) +{ + destruct( jni_env ); + delete this; +} +//__________________________________________________________________________________________________ inline void JNI_info::append_sig( - ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type ) const + ::rtl::OStringBuffer * buf, typelib_TypeDescriptionReference * type, + bool use_Object_for_type_XInterface ) { switch (type->eTypeClass) { @@ -276,11 +323,13 @@ inline void JNI_info::append_sig( { buf->append( '[' ); TypeDescr td( type ); - append_sig( buf, ((typelib_IndirectTypeDescription *)td.get())->pType ); + append_sig( + buf, ((typelib_IndirectTypeDescription *)td.get())->pType, + use_Object_for_type_XInterface ); break; } case typelib_TypeClass_INTERFACE: - if (typelib_typedescriptionreference_equals( type, m_XInterface_td.get()->pWeakRef )) + if (use_Object_for_type_XInterface && is_XInterface( type )) { buf->append( RTL_CONSTASCII_STRINGPARAM("Ljava/lang/Object;") ); } @@ -301,43 +350,6 @@ inline void JNI_info::append_sig( *reinterpret_cast< ::rtl::OUString const * >( &type->pTypeName ) ); } } -//__________________________________________________________________________________________________ -inline jobject JNI_info::java_env_getRegisteredInterface( - JNI_context const & jni, jstring oid, jobject type ) const -{ - jvalue args[ 2 ]; - args[ 0 ].l = oid; - args[ 1 ].l = type; - jobject jo_iface = jni->CallObjectMethodA( - m_object_java_env, m_method_IEnvironment_getRegisteredInterface, args ); - jni.ensure_no_exception(); - return jo_iface; -} -//__________________________________________________________________________________________________ -inline jobject JNI_info::java_env_registerInterface( - JNI_context const & jni, jobject javaI, jstring oid, jobject type ) const -{ - JLocalAutoRef jo_string_array( jni, jni->NewObjectArray( 1, m_class_String, oid ) ); - jni.ensure_no_exception(); - jvalue args[ 3 ]; - args[ 0 ].l = javaI; - args[ 1 ].l = jo_string_array.get(); - args[ 2 ].l = type; - jobject jo_iface = jni->CallObjectMethodA( - m_object_java_env, m_method_IEnvironment_registerInterface, args ); - jni.ensure_no_exception(); - return jo_iface; -} -//__________________________________________________________________________________________________ -inline void JNI_info::java_env_revokeInterface( - JNI_context const & jni, jstring oid, jobject type ) const -{ - jvalue args[ 2 ]; - args[ 0 ].l = oid; - args[ 1 ].l = type; - jni->CallVoidMethodA( m_object_java_env, m_method_IEnvironment_revokeInterface, args ); - jni.ensure_no_exception(); -} } diff --git a/bridges/source/jni_uno/jni_java2uno.cxx b/bridges/source/jni_uno/jni_java2uno.cxx index 608cd6969311..4aad711f0b1e 100644 --- a/bridges/source/jni_uno/jni_java2uno.cxx +++ b/bridges/source/jni_uno/jni_java2uno.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_java2uno.cxx,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 10:26:05 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:00 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,7 +59,7 @@ * ************************************************************************/ -#ifdef _MSC_VER +#if defined _MSC_VER #include <malloc.h> #else #include <alloca.h> @@ -76,9 +76,9 @@ namespace jni_uno { //__________________________________________________________________________________________________ -jobject Bridge::map_uno2java( +jobject Bridge::map_to_java( JNI_context const & jni, - uno_Interface * pUnoI, JNI_type_info const * info ) const + uno_Interface * pUnoI, JNI_interface_type_info const * info ) const { // get oid rtl_uString * pOid = 0; @@ -86,13 +86,17 @@ jobject Bridge::map_uno2java( OSL_ASSERT( 0 != pOid ); OUString oid( pOid, SAL_NO_ACQUIRE ); - // getRegisteredInterface() + // opt getRegisteredInterface() JLocalAutoRef jo_oid( jni, ustring_to_jstring( jni, oid.pData ) ); - JLocalAutoRef jo_iface( - jni, m_jni_info->java_env_getRegisteredInterface( - jni, (jstring)jo_oid.get(), info->m_jo_type ) ); - - if (! jo_iface.is()) // no registered iface + jvalue args[ 2 ]; + args[ 0 ].l = jo_oid.get(); + args[ 1 ].l = info->m_type; + jobject jo_iface = jni->CallObjectMethodA( + m_jni_info->m_object_java_env, + m_jni_info->m_method_IEnvironment_getRegisteredInterface, args ); + jni.ensure_no_exception(); + + if (0 == jo_iface) // no registered iface { // register uno interface (*m_uno_env->registerInterface)( @@ -100,7 +104,7 @@ jobject Bridge::map_uno2java( oid.pData, (typelib_InterfaceTypeDescription *)info->m_td.get() ); // create java and register java proxy - jvalue args[ 5 ]; + jvalue args[ 6 ]; acquire(); args[ 0 ].j = reinterpret_cast< sal_Int64 >( this ); (*pUnoI->acquire)( pUnoI ); @@ -108,16 +112,17 @@ jobject Bridge::map_uno2java( args[ 2 ].j = reinterpret_cast< sal_Int64 >( pUnoI ); typelib_typedescription_acquire( info->m_td.get() ); args[ 3 ].j = reinterpret_cast< sal_Int64 >( info->m_td.get() ); - args[ 4 ].l = info->m_jo_type; + args[ 4 ].l = info->m_type; args[ 5 ].l = jo_oid.get(); - jo_iface.reset( - jni->CallStaticObjectMethodA( - m_jni_info->m_class_JNI_proxy, - m_jni_info->m_method_JNI_proxy_create, args ) ); + args[ 6 ].l = info->m_proxy_ctor; + jo_iface = jni->CallStaticObjectMethodA( + m_jni_info->m_class_JNI_proxy, + m_jni_info->m_method_JNI_proxy_create, args ); jni.ensure_no_exception(); } - return jo_iface.release(); + OSL_ASSERT( 0 != jo_iface ); + return jo_iface; } //################################################################################################## @@ -127,11 +132,21 @@ void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const { if (typelib_TypeClass_EXCEPTION == uno_exc->pType->eTypeClass) { -#ifdef DEBUG +#if defined _DEBUG + // append java stack trace to Message member + *reinterpret_cast< OUString * >( uno_exc->pData ) += jni.get_stack_trace(); +#endif + +#if defined DEBUG + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("exception occured java->uno: [") ); + buf.append( *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); + buf.append( + reinterpret_cast< ::com::sun::star::uno::Exception const * >( + uno_exc->pData )->Message ); OString cstr_msg( - OUStringToOString( - OUString(uno_exc->pType->pTypeName) + OUSTR(": ") + - *(OUString const *)uno_exc->pData, RTL_TEXTENCODING_ASCII_US ) ); + OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); OSL_TRACE( cstr_msg.getStr() ); #endif // signal exception @@ -148,23 +163,31 @@ void Bridge::handle_uno_exc( JNI_context const & jni, uno_Any * uno_exc ) const throw; } uno_any_destruct( uno_exc, 0 ); + JLocalAutoRef jo_exc( jni, java_exc.l ); jint res = jni->Throw( (jthrowable)jo_exc.get() ); if (0 != res) { - OUStringBuffer buf( 64 ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("throwing java exception failed: [") ); - buf.append( *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); - buf.append( ((::com::sun::star::uno::Exception const *)uno_exc->pData)->Message ); + // call toString() + JLocalAutoRef jo_descr( + jni, jni->CallObjectMethodA( + jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) ); + jni.ensure_no_exception(); + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("throwing java exception failed: ") ); + buf.append( jstring_to_oustring( jni, (jstring)jo_descr.get() ) ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } } else { - throw BridgeRuntimeError( + OUString message( OUSTR("thrown exception is no uno exception: ") + - *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) ); + *reinterpret_cast< OUString const * >( &uno_exc->pType->pTypeName ) + + jni.get_stack_trace() ); + uno_any_destruct( uno_exc, 0 ); + throw BridgeRuntimeError( message ); } } @@ -179,15 +202,14 @@ union largest jobject Bridge::call_uno( JNI_context const & jni, uno_Interface * pUnoI, typelib_TypeDescription * member_td, - typelib_TypeDescriptionReference * return_type /* 0 indicates void return */, + typelib_TypeDescriptionReference * return_type, sal_Int32 nParams, typelib_MethodParameter const * pParams, jobjectArray jo_args /* may be 0 */ ) const { // return mem sal_Int32 return_size = sizeof (largest); - if ((0 != return_type) && - (typelib_TypeClass_STRUCT == return_type->eTypeClass || - typelib_TypeClass_EXCEPTION == return_type->eTypeClass)) + if (typelib_TypeClass_STRUCT == return_type->eTypeClass || + typelib_TypeClass_EXCEPTION == return_type->eTypeClass) { TypeDescr return_td( return_type ); if (return_td.get()->nSize > sizeof (largest)) @@ -217,12 +239,12 @@ jobject Bridge::call_uno( if (param.bIn) { - JLocalAutoRef jo_arg( jni, jni->GetObjectArrayElement( jo_args, nPos ) ); - jni.ensure_no_exception(); - jvalue java_arg; - java_arg.l = jo_arg.get(); try { + JLocalAutoRef jo_arg( jni, jni->GetObjectArrayElement( jo_args, nPos ) ); + jni.ensure_no_exception(); + jvalue java_arg; + java_arg.l = jo_arg.get(); map_to_uno( jni, uno_args[ nPos ], java_arg, type, 0, false /* no assign */, sal_False != param.bOut, @@ -233,11 +255,9 @@ jobject Bridge::call_uno( // cleanup uno in args for ( sal_Int32 n = 0; n < nPos; ++n ) { - typelib_MethodParameter const & param = pParams[ nPos ]; + typelib_MethodParameter const & param = pParams[ n ]; if (param.bIn) - { - uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 ); - } + uno_type_destructData( uno_args[ n ], param.pTypeRef, 0 ); } throw; } @@ -255,6 +275,7 @@ jobject Bridge::call_uno( for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) { typelib_MethodParameter const & param = pParams[ nPos ]; + typelib_TypeDescriptionReference * type = param.pTypeRef; if (param.bOut) { try @@ -266,7 +287,7 @@ jobject Bridge::call_uno( jvalue java_arg; java_arg.l = jo_out_holder.get(); map_to_java( - jni, &java_arg, uno_args[ nPos ], param.pTypeRef, 0, + jni, &java_arg, uno_args[ nPos ], type, 0, true /* in */, true /* out holder */ ); } catch (...) @@ -274,37 +295,42 @@ jobject Bridge::call_uno( // cleanup further uno args for ( sal_Int32 n = nPos; n < nParams; ++n ) { - uno_type_destructData( uno_args[ nPos ], pParams[ nPos ].pTypeRef, 0 ); + uno_type_destructData( uno_args[ n ], pParams[ n ].pTypeRef, 0 ); } // cleanup uno return value - if (0 != return_type) - { - uno_type_destructData( uno_ret, return_type, 0 ); - } + uno_type_destructData( uno_ret, return_type, 0 ); throw; } } - uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 ); + if (typelib_TypeClass_DOUBLE < type->eTypeClass && + typelib_TypeClass_ENUM != type->eTypeClass) // opt + { + uno_type_destructData( uno_args[ nPos ], type, 0 ); + } } - if ((0 != return_type) && - (typelib_TypeClass_VOID != return_type->eTypeClass)) + if (typelib_TypeClass_VOID != return_type->eTypeClass) { // convert uno return value + jvalue java_ret; try { - jvalue java_ret; map_to_java( jni, &java_ret, uno_ret, return_type, 0, true /* in */, false /* no out */, true /* special_wrapped_integral_types */ ); - return java_ret.l; } catch (...) { uno_type_destructData( uno_ret, return_type, 0 ); throw; } + if (typelib_TypeClass_DOUBLE < return_type->eTypeClass && + typelib_TypeClass_ENUM != return_type->eTypeClass) // opt + { + uno_type_destructData( uno_ret, return_type, 0 ); + } + return java_ret.l; } return 0; // void return } @@ -315,9 +341,7 @@ jobject Bridge::call_uno( { typelib_MethodParameter const & param = pParams[ nPos ]; if (param.bIn) - { uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 ); - } } handle_uno_exc( jni, uno_exc ); @@ -342,10 +366,12 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch JNI_info const * jni_info = bridge->m_jni_info; JNI_context jni( jni_info, jni_env ); + OUString method_name; + try { - OUString method_name( jstring_to_oustring( jni, jo_method ) ); -#ifdef DEBUG + method_name = jstring_to_oustring( jni, jo_method ); +#if defined DEBUG OUStringBuffer trace_buf( 64 ); trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("java->uno call: ") ); trace_buf.append( method_name ); @@ -372,19 +398,30 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch jni, jni->GetObjectField( jo_type.get(), jni_info->m_field_Type__typeName ) ); if (! jo_type_name.is()) - throw BridgeRuntimeError( OUSTR("incomplete type object: no type name!") ); + { + throw BridgeRuntimeError( + OUSTR("incomplete type object: no type name!") + jni.get_stack_trace() ); + } OUString type_name( jstring_to_oustring( jni, (jstring)jo_type_name.get() ) ); JNI_type_info const * info = jni_info->get_type_info( jni, type_name ); + if (typelib_TypeClass_INTERFACE != info->m_td.get()->eTypeClass) + { + throw BridgeRuntimeError( + OUSTR("queryInterface() call demands an INTERFACE type!") ); + } + JNI_interface_type_info const * iface_info = + static_cast< JNI_interface_type_info const * >( info ); - // getRegisteredInterface() already tested in JNI_proxy + // getRegisteredInterface() already tested in JNI_proxy: // perform queryInterface call on binary uno interface uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >( jni->GetLongField( jo_proxy, jni_info->m_field_JNI_proxy_m_receiver_handle ) ); uno_Any uno_ret; - void * uno_args[] = { &info->m_td.get()->pWeakRef }; - uno_Any * uno_exc; + void * uno_args[] = { &iface_info->m_td.get()->pWeakRef }; + uno_Any uno_exc_holder; + uno_Any * uno_exc = &uno_exc_holder; // call binary uno (*pUnoI->pDispatcher)( pUnoI, jni_info->m_XInterface_queryInterface_td.get(), @@ -399,7 +436,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch { try { - jo_ret = bridge->map_uno2java( jni, pUnoRet, info ); + jo_ret = bridge->map_to_java( jni, pUnoRet, iface_info ); } catch (...) { @@ -439,6 +476,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ") does not fit with called interface: ") ); buf.append( iface_name ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } @@ -463,14 +501,15 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch (0 == rtl_ustr_compare( method_name.getStr(), type_name.getStr() + type_name.getLength() - method_name.getLength() ) - /* ends with method_name: */)) + /* ends with method_name */)) { TypeDescr member_td( member_type ); typelib_InterfaceMethodTypeDescription * method_td = (typelib_InterfaceMethodTypeDescription *)member_td.get(); return bridge->call_uno( jni, pUnoI, member_td.get(), - method_td->pReturnTypeRef, method_td->nParams, method_td->pParams, + method_td->pReturnTypeRef, + method_td->nParams, method_td->pParams, jo_args ); } } @@ -485,7 +524,7 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch (0 == rtl_ustr_compare( method_name.getStr() +3, type_name.getStr() + type_name.getLength() - method_name.getLength() +3 ) - /* ends with method_name.copy(3): */)) + /* ends with method_name.copy(3) */)) { if ('g' == method_name[ 0 ]) { @@ -494,7 +533,8 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch (typelib_InterfaceAttributeTypeDescription *)member_td.get(); return bridge->call_uno( jni, pUnoI, member_td.get(), - attribute_td->pAttributeTypeRef, 0, 0, + attribute_td->pAttributeTypeRef, + 0, 0, jo_args ); } else if ('s' == method_name[ 0 ]) @@ -510,7 +550,8 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch param.bOut = sal_False; return bridge->call_uno( jni, pUnoI, member_td.get(), - 0 /* indicates void return */, 1, ¶m, + jni_info->m_void_type.getTypeLibType(), + 1, ¶m, jo_args ); } } @@ -525,14 +566,20 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch &((typelib_TypeDescription *)td)->pTypeName ) ); buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); buf.append( method_name ); + buf.append( jni.get_stack_trace() ); throw BridgeRuntimeError( buf.makeStringAndClear() ); } catch (BridgeRuntimeError & err) { + OUStringBuffer buf( 128 ); + buf.appendAscii( + RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] Java calling UNO method ") ); + buf.append( method_name ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); + buf.append( err.m_message ); // notify RuntimeException OString cstr_msg( - OUStringToOString( - OUSTR("[jni_uno bridge error] ") + err.m_message, RTL_TEXTENCODING_ASCII_US ) ); + OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); OSL_ENSURE( 0, cstr_msg.getStr() ); jint res = jni->ThrowNew( jni_info->m_class_RuntimeException, cstr_msg.getStr() ); OSL_ASSERT( 0 == res ); @@ -541,8 +588,9 @@ JNIEXPORT jobject JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_dispatch catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &) { OString cstr_msg( - RTL_CONSTASCII_STRINGPARAM( - "[jni_uno bridge error] attaching current thread to java failed!") ); + OString( RTL_CONSTASCII_STRINGPARAM( + "[jni_uno bridge error] attaching current thread to java failed!") ) + + OUStringToOString( jni.get_stack_trace(), RTL_TEXTENCODING_ASCII_US ) ); OSL_ENSURE( 0, cstr_msg.getStr() ); jint res = jni->ThrowNew( jni_info->m_class_RuntimeException, cstr_msg.getStr() ); OSL_ASSERT( 0 == res ); @@ -563,7 +611,7 @@ JNIEXPORT void JNICALL Java_com_sun_star_bridges_jni_1uno_JNI_1proxy_finalize__J typelib_TypeDescription * td = reinterpret_cast< typelib_TypeDescription * >( jni->GetLongField( jo_proxy, jni_info->m_field_JNI_proxy_m_td_handle ) ); -#ifdef DEBUG +#if defined DEBUG JLocalAutoRef jo_oid( jni, jni->GetObjectField( jo_proxy, jni_info->m_field_JNI_proxy_m_oid ) ); OUString oid( jstring_to_oustring( jni, (jstring)jo_oid.get() ) ); diff --git a/bridges/source/jni_uno/jni_uno2java.cxx b/bridges/source/jni_uno/jni_uno2java.cxx index 17968fdaa382..c571ea380a17 100644 --- a/bridges/source/jni_uno/jni_uno2java.cxx +++ b/bridges/source/jni_uno/jni_uno2java.cxx @@ -2,9 +2,9 @@ * * $RCSfile: jni_uno2java.cxx,v $ * - * $Revision: 1.10 $ + * $Revision: 1.11 $ * - * last change: $Author: dbo $ $Date: 2002-12-06 10:26:05 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:01 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,15 +59,13 @@ * ************************************************************************/ -#ifdef _MSC_VER +#if defined _MSC_VER #include <malloc.h> #else #include <alloca.h> #endif -#ifdef DEBUG #include "rtl/ustrbuf.hxx" -#endif #include "jni_bridge.h" @@ -107,10 +105,16 @@ void Bridge::handle_java_exc( if (! jo_exc.is()) { throw BridgeRuntimeError( - OUSTR("java exception occured, but no java exception available!?") ); + OUSTR("java exception occured, but no java exception available!?") + + jni.get_stack_trace() ); } - OUString exc_name( get_class_name( jni, jo_exc.get() ) ); + JLocalAutoRef jo_class( jni, jni->GetObjectClass( jo_exc.get() ) ); + JLocalAutoRef jo_class_name( + jni, jni->CallObjectMethodA( jo_class.get(), m_jni_info->m_method_Class_getName, 0 ) ); + jni.ensure_no_exception(); + OUString exc_name( jstring_to_oustring( jni, (jstring)jo_class_name.get() ) ); + ::com::sun::star::uno::TypeDescription td( exc_name.pData ); if (!td.is() || (typelib_TypeClass_EXCEPTION != td.get()->eTypeClass)) { @@ -119,8 +123,11 @@ void Bridge::handle_java_exc( jni, jni->CallObjectMethodA( jo_exc.get(), m_jni_info->m_method_Object_toString, 0 ) ); jni.ensure_no_exception(); - OUString descr( jstring_to_oustring( jni, (jstring)jo_descr.get() ) ); - throw BridgeRuntimeError( OUSTR("non-UNO exception occurred: ") + descr ); + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("non-UNO exception occurred: ") ); + buf.append( jstring_to_oustring( jni, (jstring)jo_descr.get() ) ); + buf.append( jni.get_stack_trace( jo_exc.get() ) ); + throw BridgeRuntimeError( buf.makeStringAndClear() ); } auto_ptr< rtl_mem > uno_data( rtl_mem::allocate( td.get()->nSize ) ); @@ -130,21 +137,19 @@ void Bridge::handle_java_exc( jni, uno_data.get(), val, td.get()->pWeakRef, 0, false /* no assign */, false /* no out param */ ); +#if defined _DEBUG + // patch Message, append stack trace + *reinterpret_cast< OUString * >( uno_data.get() ) += jni.get_stack_trace( jo_exc.get() ); +#endif + typelib_typedescriptionreference_acquire( td.get()->pWeakRef ); uno_exc->pType = td.get()->pWeakRef; uno_exc->pData = uno_data.release(); -#ifdef DEBUG - OString cstr_msg( - OUStringToOString( - OUString(uno_exc->pType->pTypeName) + OUSTR(": ") + - *(OUString const *)uno_exc->pData, RTL_TEXTENCODING_ASCII_US ) ); - OSL_TRACE( cstr_msg.getStr() ); -#endif } //__________________________________________________________________________________________________ void Bridge::call_java( - jobject javaI, JNI_type_info const * info, sal_Int32 function_pos, - typelib_TypeDescriptionReference * return_type /* 0 indicates void return */, + jobject javaI, JNI_interface_type_info const * info, sal_Int32 function_pos, + typelib_TypeDescriptionReference * return_type, typelib_MethodParameter * params, sal_Int32 nParams, void * uno_ret, void * uno_args [], uno_Any ** uno_exc ) const { @@ -159,7 +164,7 @@ void Bridge::call_java( function_pos -= base_functions; break; } - info = info->m_base; + info = static_cast< JNI_interface_type_info const * >( info->m_base ); } JNI_guarded_context jni( @@ -171,10 +176,10 @@ void Bridge::call_java( sal_Int32 nPos; for ( nPos = 0; nPos < nParams; ++nPos ) { - typelib_MethodParameter const & param = params[ nPos ]; try { - java_args[ nPos ].l = 0; // build up array[ 1 ] + typelib_MethodParameter const & param = params[ nPos ]; + java_args[ nPos ].l = 0; // if out: build up array[ 1 ] map_to_java( jni, &java_args[ nPos ], uno_args[ nPos ], @@ -187,6 +192,7 @@ void Bridge::call_java( // cleanup for ( sal_Int32 n = 0; n < nPos; ++n ) { + typelib_MethodParameter const & param = params[ n ]; if (param.bOut || typelib_TypeClass_DOUBLE < param.pTypeRef->eTypeClass) jni->DeleteLocalRef( java_args[ n ].l ); } @@ -198,48 +204,41 @@ void Bridge::call_java( JLocalAutoRef java_ret( jni ); jmethodID method_id = info->m_methods[ function_pos ]; - if (0 == return_type) // indicates void return + switch (return_type->eTypeClass) { + case typelib_TypeClass_VOID: jni->CallVoidMethodA( javaI, method_id, java_args ); - } - else - { - switch (return_type->eTypeClass) - { - case typelib_TypeClass_VOID: - jni->CallVoidMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_CHAR: - *(sal_Unicode *)uno_ret = jni->CallCharMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_BOOLEAN: - *(sal_Bool *)uno_ret = jni->CallBooleanMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_BYTE: - *(sal_Int8 *)uno_ret = jni->CallByteMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_SHORT: - case typelib_TypeClass_UNSIGNED_SHORT: - *(sal_Int16 *)uno_ret = jni->CallShortMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_LONG: - case typelib_TypeClass_UNSIGNED_LONG: - *(sal_Int32 *)uno_ret = jni->CallIntMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_HYPER: - case typelib_TypeClass_UNSIGNED_HYPER: - *(sal_Int64 *)uno_ret = jni->CallLongMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_FLOAT: - *(float *)uno_ret = jni->CallFloatMethodA( javaI, method_id, java_args ); - break; - case typelib_TypeClass_DOUBLE: - *(double *)uno_ret = jni->CallDoubleMethodA( javaI, method_id, java_args ); - break; - default: - java_ret.reset( jni->CallObjectMethodA( javaI, method_id, java_args ) ); - break; - } + break; + case typelib_TypeClass_CHAR: + *(sal_Unicode *)uno_ret = jni->CallCharMethodA( javaI, method_id, java_args ); + break; + case typelib_TypeClass_BOOLEAN: + *(sal_Bool *)uno_ret = jni->CallBooleanMethodA( javaI, method_id, java_args ); + break; + case typelib_TypeClass_BYTE: + *(sal_Int8 *)uno_ret = jni->CallByteMethodA( javaI, method_id, java_args ); + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + *(sal_Int16 *)uno_ret = jni->CallShortMethodA( javaI, method_id, java_args ); + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + *(sal_Int32 *)uno_ret = jni->CallIntMethodA( javaI, method_id, java_args ); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + *(sal_Int64 *)uno_ret = jni->CallLongMethodA( javaI, method_id, java_args ); + break; + case typelib_TypeClass_FLOAT: + *(float *)uno_ret = jni->CallFloatMethodA( javaI, method_id, java_args ); + break; + case typelib_TypeClass_DOUBLE: + *(double *)uno_ret = jni->CallDoubleMethodA( javaI, method_id, java_args ); + break; + default: + java_ret.reset( jni->CallObjectMethodA( javaI, method_id, java_args ) ); + break; } if (jni->ExceptionCheck()) @@ -262,7 +261,6 @@ void Bridge::call_java( for ( nPos = 0; nPos < nParams; ++nPos ) { typelib_MethodParameter const & param = params[ nPos ]; - if (param.bOut) { try @@ -270,8 +268,6 @@ void Bridge::call_java( map_to_uno( jni, uno_args[ nPos ], java_args[ nPos ], param.pTypeRef, 0, sal_False != param.bIn /* assign if inout */, true /* out param */ ); - // out array - jni->DeleteLocalRef( java_args[ nPos ].l ); } catch (...) { @@ -291,6 +287,7 @@ void Bridge::call_java( } throw; } + jni->DeleteLocalRef( java_args[ nPos ].l ); } else // pure temp in param { @@ -300,15 +297,28 @@ void Bridge::call_java( } // return value - if ((0 != return_type) && - (typelib_TypeClass_DOUBLE < return_type->eTypeClass)) // complex + if (typelib_TypeClass_DOUBLE < return_type->eTypeClass) { - jvalue val; - val.l = java_ret.get(); - map_to_uno( - jni, uno_ret, val, return_type, 0, - false /* no assign */, false /* no out param */ ); - } // else already set integral uno return value + try + { + jvalue val; + val.l = java_ret.get(); + map_to_uno( + jni, uno_ret, val, return_type, 0, + false /* no assign */, false /* no out param */ ); + } + catch (...) + { + // cleanup uno pure out + for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos ) + { + typelib_MethodParameter const & param = params[ nPos ]; + if (! param.bIn) + uno_type_destructData( uno_args[ nPos ], param.pTypeRef, 0 ); + } + throw; + } + } // else: already set integral uno return value // no exception occured *uno_exc = 0; @@ -322,10 +332,10 @@ struct UNO_proxy : public uno_Interface Bridge const * m_bridge; // mapping information - OUString m_oid; jobject m_javaI; jstring m_jo_oid; - JNI_type_info const * m_type_info; + OUString m_oid; + JNI_interface_type_info const * m_type_info; inline void acquire() const; inline void release() const; @@ -333,20 +343,32 @@ struct UNO_proxy : public uno_Interface // ctor inline UNO_proxy( JNI_context const & jni, Bridge const * bridge, - jobject javaI, jstring jo_oid, OUString const & oid, JNI_type_info const * info ); + jobject javaI, jstring jo_oid, OUString const & oid, JNI_interface_type_info const * info ); }; //__________________________________________________________________________________________________ inline UNO_proxy::UNO_proxy( JNI_context const & jni, Bridge const * bridge, - jobject javaI, jstring jo_oid, OUString const & oid, JNI_type_info const * info ) + jobject javaI, jstring jo_oid, OUString const & oid, JNI_interface_type_info const * info ) : m_ref( 1 ), m_oid( oid ), m_type_info( info ) { + JNI_info const * jni_info = bridge->m_jni_info; + JLocalAutoRef jo_string_array( + jni, jni->NewObjectArray( 1, jni_info->m_class_String, jo_oid ) ); + jni.ensure_no_exception(); + jvalue args[ 3 ]; + args[ 0 ].l = javaI; + args[ 1 ].l = jo_string_array.get(); + args[ 2 ].l = info->m_type; + jobject jo_iface = jni->CallObjectMethodA( + jni_info->m_object_java_env, jni_info->m_method_IEnvironment_registerInterface, args ); + jni.ensure_no_exception(); + + m_javaI = jni->NewGlobalRef( jo_iface ); + m_jo_oid = (jstring)jni->NewGlobalRef( jo_oid ); bridge->acquire(); m_bridge = bridge; - m_javaI = jni->NewGlobalRef( javaI ); - m_jo_oid = (jstring)jni->NewGlobalRef( jo_oid ); // uno_Interface uno_Interface::acquire = UNO_proxy_acquire; @@ -365,7 +387,7 @@ inline void UNO_proxy::acquire() const m_bridge->m_uno_env, &that, UNO_proxy_free, m_oid.pData, (typelib_InterfaceTypeDescription *)m_type_info->m_td.get() ); -#ifdef DEBUG +#if defined DEBUG OSL_ASSERT( this == (void const * const)that ); #endif } @@ -384,9 +406,9 @@ inline void UNO_proxy::release() const //################################################################################################## //__________________________________________________________________________________________________ -uno_Interface * Bridge::map_java2uno( +uno_Interface * Bridge::map_to_uno( JNI_context const & jni, - jobject javaI, JNI_type_info const * info ) const + jobject javaI, JNI_interface_type_info const * info ) const { JLocalAutoRef jo_oid( jni, compute_oid( jni, javaI ) ); OUString oid( jstring_to_oustring( jni, (jstring)jo_oid.get() ) ); @@ -398,14 +420,10 @@ uno_Interface * Bridge::map_java2uno( if (0 == pUnoI) // no existing interface, register new proxy { - JLocalAutoRef jo_iface( - jni, m_jni_info->java_env_registerInterface( - jni, javaI, (jstring)jo_oid.get(), info->m_jo_type ) ); - // refcount initially 1 pUnoI = new UNO_proxy( jni, const_cast< Bridge * >( this ), - jo_iface.get(), (jstring)jo_oid.get(), oid, info ); + javaI, (jstring)jo_oid.get(), oid, info ); (*m_uno_env->registerProxyInterface)( m_uno_env, (void **)&pUnoI, @@ -429,8 +447,10 @@ void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy ) SAL_THROW_EXTERN_C() { UNO_proxy const * that = reinterpret_cast< UNO_proxy const * >( proxy ); - OSL_ASSERT( env == that->m_bridge->m_uno_env ); -#ifdef DEBUG + Bridge const * bridge = that->m_bridge; + + OSL_ASSERT( env == bridge->m_uno_env ); +#if defined DEBUG OString cstr_msg( OUStringToOString( OUSTR("freeing binary uno proxy: ") + that->m_oid, RTL_TEXTENCODING_ASCII_US ) ); @@ -439,34 +459,16 @@ void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy ) try { - Bridge const * bridge = that->m_bridge; JNI_guarded_context jni( bridge->m_jni_info, reinterpret_cast< ::jvmaccess::VirtualMachine * >( bridge->m_java_env->pContext ) ); - try - { - bridge->m_jni_info->java_env_revokeInterface( - jni, that->m_jo_oid, that->m_type_info->m_jo_type ); - } - catch (BridgeRuntimeError & err) - { -#ifdef _DEBUG - OString cstr_msg( OUStringToOString( err.m_message, RTL_TEXTENCODING_ASCII_US ) ); - OSL_ENSURE( 0, cstr_msg.getStr() ); -#endif - } - catch (::jvmaccess::VirtualMachine::AttachGuard::CreationException &) - { - OSL_ENSURE( 0, "[jni_uno bridge error] attaching current thread to java failed!" ); - } - jni->DeleteGlobalRef( that->m_javaI ); jni->DeleteGlobalRef( that->m_jo_oid ); } catch (BridgeRuntimeError & err) { -#ifdef _DEBUG +#if defined _DEBUG OString cstr_msg( OUStringToOString( err.m_message, RTL_TEXTENCODING_ASCII_US ) ); OSL_ENSURE( 0, cstr_msg.getStr() ); #endif @@ -476,8 +478,8 @@ void SAL_CALL UNO_proxy_free( uno_ExtEnvironment * env, void * proxy ) OSL_ENSURE( 0, "[jni_uno bridge error] attaching current thread to java failed!" ); } - that->m_bridge->release(); -#ifdef DEBUG + bridge->release(); +#if defined DEBUG *(int *)that = 0xdeadcafe; #endif delete that; @@ -504,7 +506,9 @@ void SAL_CALL UNO_proxy_dispatch( SAL_THROW_EXTERN_C() { UNO_proxy const * that = static_cast< UNO_proxy const * >( pUnoI ); -#ifdef DEBUG + Bridge const * bridge = that->m_bridge; + +#if defined DEBUG OUStringBuffer trace_buf( 64 ); trace_buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("uno->java call: ") ); trace_buf.append( *reinterpret_cast< OUString const * >( &member_td->pTypeName ) ); @@ -517,8 +521,6 @@ void SAL_CALL UNO_proxy_dispatch( try { - Bridge const * bridge = that->m_bridge; - switch (member_td->eTypeClass) { case typelib_TypeClass_INTERFACE_ATTRIBUTE: @@ -552,7 +554,8 @@ void SAL_CALL UNO_proxy_dispatch( bridge->call_java( that->m_javaI, that->m_type_info, function_pos +1, // get, then set method - 0 /* indicates void return */, ¶m, 1, + bridge->m_jni_info->m_void_type.getTypeLibType(), + ¶m, 1, 0, uno_args, uno_exc ); } break; @@ -597,11 +600,12 @@ void SAL_CALL UNO_proxy_dispatch( reinterpret_cast< ::jvmaccess::VirtualMachine * >( bridge->m_java_env->pContext ) ); - JNI_type_info const * info = - jni_info->get_type_info( jni, demanded_td.get() ); + JNI_interface_type_info const * info = + static_cast< JNI_interface_type_info const * >( + jni_info->get_type_info( jni, demanded_td.get() ) ); jvalue args[ 2 ]; - args[ 0 ].l = info->m_jo_type; + args[ 0 ].l = info->m_type; args[ 1 ].l = that->m_javaI; JLocalAutoRef jo_ret( @@ -619,18 +623,14 @@ void SAL_CALL UNO_proxy_dispatch( { if (jo_ret.is()) { -#ifdef _DEBUG +#if defined _DEBUG JLocalAutoRef jo_oid( jni, compute_oid( jni, jo_ret.get() ) ); OUString oid( jstring_to_oustring( jni, (jstring)jo_oid.get() ) ); OSL_ENSURE( oid.equals( that->m_oid ), "### different oids!" ); #endif - JLocalAutoRef jo_iface( - jni, jni_info->java_env_registerInterface( - jni, jo_ret.get(), that->m_jo_oid, info->m_jo_type ) ); - // refcount initially 1 uno_Interface * pUnoI = new UNO_proxy( - jni, bridge, jo_iface.get(), + jni, bridge, jo_ret.get(), that->m_jo_oid, that->m_oid, info ); (*bridge->m_uno_env->registerProxyInterface)( @@ -674,7 +674,8 @@ void SAL_CALL UNO_proxy_dispatch( (typelib_InterfaceMethodTypeDescription *)member_td; bridge->call_java( that->m_javaI, that->m_type_info, function_pos, - method_td->pReturnTypeRef, method_td->pParams, method_td->nParams, + method_td->pReturnTypeRef, + method_td->pParams, method_td->nParams, uno_ret, uno_args, uno_exc ); break; } @@ -686,16 +687,45 @@ void SAL_CALL UNO_proxy_dispatch( throw BridgeRuntimeError( OUSTR("illegal member type description!") ); } } + +#if defined DEBUG + if (0 != *uno_exc) + { + OUStringBuffer buf( 128 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("exception occured uno->java: [") ); + buf.append( *reinterpret_cast< OUString const * >( &(*uno_exc)->pType->pTypeName ) ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") ); + buf.append( + reinterpret_cast< ::com::sun::star::uno::Exception const * >( + (*uno_exc)->pData )->Message ); + OString cstr_msg( + OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); + OSL_TRACE( cstr_msg.getStr() ); + } +#endif } catch (BridgeRuntimeError & err) { + OUStringBuffer buf( 128 ); + buf.appendAscii( + RTL_CONSTASCII_STRINGPARAM("[jni_uno bridge error] UNO calling Java method ") ); + if (typelib_TypeClass_INTERFACE_METHOD == member_td->eTypeClass || + typelib_TypeClass_INTERFACE_ATTRIBUTE == member_td->eTypeClass) + { + buf.append( + *reinterpret_cast< OUString const * >( + &reinterpret_cast< typelib_InterfaceMemberTypeDescription const * >( + member_td )->pMemberName ) ); + } + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(": ") ); + buf.append( err.m_message ); // binary identical struct ::com::sun::star::uno::RuntimeException exc( - OUSTR("[jni_uno bridge error] ") + err.m_message, + buf.makeStringAndClear(), ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc ); uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 ); -#ifdef _DEBUG +#if defined _DEBUG OString cstr_msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); OSL_ENSURE( 0, cstr_msg.getStr() ); #endif @@ -708,7 +738,7 @@ void SAL_CALL UNO_proxy_dispatch( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() ); ::com::sun::star::uno::Type const & exc_type = ::getCppuType( &exc ); uno_type_any_construct( *uno_exc, &exc, exc_type.getTypeLibType(), 0 ); -#ifdef _DEBUG +#if defined _DEBUG OString cstr_msg( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) ); OSL_ENSURE( 0, cstr_msg.getStr() ); #endif diff --git a/bridges/source/remote/static/proxy.cxx b/bridges/source/remote/static/proxy.cxx index ddca7b343d85..007d72abeb6e 100644 --- a/bridges/source/remote/static/proxy.cxx +++ b/bridges/source/remote/static/proxy.cxx @@ -2,9 +2,9 @@ * * $RCSfile: proxy.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: svesik $ $Date: 2002-08-27 13:38:00 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:07 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -59,7 +59,7 @@ * ************************************************************************/ #include <assert.h> -#if defined(SOLARIS) || defined(IRIX) +#ifdef SOLARIS #include <alloca.h> #elif defined MACOSX #include <sys/types.h> diff --git a/bridges/source/remote/static/stub.cxx b/bridges/source/remote/static/stub.cxx index 86b6d80a598d..344c40b96930 100644 --- a/bridges/source/remote/static/stub.cxx +++ b/bridges/source/remote/static/stub.cxx @@ -2,9 +2,9 @@ * * $RCSfile: stub.cxx,v $ * - * $Revision: 1.3 $ + * $Revision: 1.4 $ * - * last change: $Author: svesik $ $Date: 2002-08-27 13:38:01 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:07 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -58,7 +58,7 @@ * * ************************************************************************/ -#if defined(SOLARIS) || defined(IRIX) +#ifdef SOLARIS #include <alloca.h> #elif defined MACOSX #include <sys/types.h> diff --git a/bridges/source/remote/urp/urp_dispatch.cxx b/bridges/source/remote/urp/urp_dispatch.cxx index 6ae9cc873442..317c379b962c 100644 --- a/bridges/source/remote/urp/urp_dispatch.cxx +++ b/bridges/source/remote/urp/urp_dispatch.cxx @@ -2,9 +2,9 @@ * * $RCSfile: urp_dispatch.cxx,v $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * - * last change: $Author: svesik $ $Date: 2002-08-27 13:43:55 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:08 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -58,7 +58,7 @@ * * ************************************************************************/ -#if defined(SOLARIS) || defined(IRIX) +#ifdef SOLARIS #include <alloca.h> #elif MACOSX #include <sys/types.h> diff --git a/bridges/source/remote/urp/urp_marshal.hxx b/bridges/source/remote/urp/urp_marshal.hxx index a2a2b86b865e..b2d0ca0195d3 100644 --- a/bridges/source/remote/urp/urp_marshal.hxx +++ b/bridges/source/remote/urp/urp_marshal.hxx @@ -2,9 +2,9 @@ * * $RCSfile: urp_marshal.hxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: hr $ $Date: 2002-02-21 12:11:45 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:08 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -61,8 +61,6 @@ #ifndef _URP_MARSHAL_HXX_ #define _URP_MARSHAL_HXX_ -#include <string.h> - #ifndef _RTL_USTRBUF_HXX_ #include <rtl/ustrbuf.hxx> #endif diff --git a/bridges/source/remote/urp/urp_reader.cxx b/bridges/source/remote/urp/urp_reader.cxx index 2869fdc0102f..2d8d46159172 100644 --- a/bridges/source/remote/urp/urp_reader.cxx +++ b/bridges/source/remote/urp/urp_reader.cxx @@ -2,9 +2,9 @@ * * $RCSfile: urp_reader.cxx,v $ * - * $Revision: 1.9 $ + * $Revision: 1.10 $ * - * last change: $Author: jbu $ $Date: 2001-08-31 16:16:52 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:08 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -132,7 +132,6 @@ namespace bridges_urp //--------------------------- }; // end struct MessageFlags - inline sal_Bool OReaderThread::getMemberTypeDescription( typelib_InterfaceAttributeTypeDescription **ppAttributeType, typelib_InterfaceMethodTypeDescription **ppMethodType, @@ -142,9 +141,10 @@ inline sal_Bool OReaderThread::getMemberTypeDescription( { if( pITypeRef->eTypeClass != typelib_TypeClass_INTERFACE ) { - OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "interface type is not of typeclass interface (" )); - sMessage += OUString::valueOf( (sal_Int32) pITypeRef->eTypeClass ); - m_pBridgeImpl->addError( sMessage ); + OUStringBuffer sMessage; + sMessage.appendAscii( "interface type is not of typeclass interface (" ); + sMessage.append( (sal_Int32) pITypeRef->eTypeClass ); + m_pBridgeImpl->addError( sMessage.makeStringAndClear() ); OSL_ENSURE( 0 , "type is not an interface" ); return sal_False; } @@ -154,9 +154,10 @@ inline sal_Bool OReaderThread::getMemberTypeDescription( (typelib_TypeDescription **)&pInterfaceType , pITypeRef ); if( ! pInterfaceType ) { - OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "No typedescription can be retrieved for type " )); - sMessage += pITypeRef->pTypeName; - m_pBridgeImpl->addError( sMessage ); + OUStringBuffer sMessage; + sMessage.appendAscii( "No typedescription can be retrieved for type " ); + sMessage.append( OUString( pITypeRef->pTypeName ) ); + m_pBridgeImpl->addError( sMessage.makeStringAndClear() ); OSL_ENSURE( 0 , "urp: unknown type " ); return sal_False; } @@ -166,32 +167,31 @@ inline sal_Bool OReaderThread::getMemberTypeDescription( typelib_typedescription_complete( (typelib_TypeDescription **) &pInterfaceType ); } - if( nMethodId < 0 || nMethodId > pInterfaceType->nAllMembers *2 ) + if ( nMethodId < 0 || nMethodId >= pInterfaceType->nMapFunctionIndexToMemberIndex ) { - OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "vtable out of range for type " )); - sMessage += pITypeRef->pTypeName; - sMessage += OUString::createFromAscii( " (" ); - sMessage += OUString::valueOf( (sal_Int32) nMethodId ); - sMessage += OUString::createFromAscii( " )" ); - m_pBridgeImpl->addError( sMessage ); - - // (nMethodId > pInterfaceType->nAllMembers *2) is an essential condition - // for the vtable index to be correct - OSL_ENSURE( 0 , "vtable index out of range" ); - return sal_False; + OUStringBuffer sMessage; + sMessage.appendAscii( "vtable out of range for type " ); + sMessage.append( OUString( pITypeRef->pTypeName ) ); + sMessage.appendAscii( " (" ); + sMessage.append( (sal_Int32) nMethodId ); + sMessage.appendAscii( " )" ); + m_pBridgeImpl->addError( sMessage.makeStringAndClear() ); + + OSL_ENSURE( 0 , "vtable index out of range" ); + return sal_False; } - // TODO : check the range of nMethodId sal_Int32 nMemberIndex = pInterfaceType->pMapFunctionIndexToMemberIndex[ nMethodId ]; if( !( pInterfaceType->nAllMembers > nMemberIndex && nMemberIndex >= 0 ) ) { - OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "vtable out of range for type " )); - sMessage += pITypeRef->pTypeName; - sMessage += OUString::createFromAscii( " (" ); - sMessage += OUString::valueOf( (sal_Int32) nMethodId ); - sMessage += OUString::createFromAscii( " )" ); - m_pBridgeImpl->addError( sMessage ); + OUStringBuffer sMessage; + sMessage.appendAscii( "vtable out of range for type " ); + sMessage.append( OUString( pITypeRef->pTypeName ) ); + sMessage.appendAscii( " (" ); + sMessage.append( (sal_Int32) nMethodId ); + sMessage.appendAscii( " )" ); + m_pBridgeImpl->addError( sMessage.makeStringAndClear() ); OSL_ENSURE( 0 , "vtable index out of range" ); return sal_False; @@ -203,12 +203,13 @@ inline sal_Bool OReaderThread::getMemberTypeDescription( if(! pMemberType ) { - OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "unknown method type description for type" ) ); - sMessage += pITypeRef->pTypeName; - sMessage += OUString::createFromAscii( " (" ); - sMessage += OUString::valueOf( (sal_Int32) nMethodId ); - sMessage += OUString::createFromAscii( " )" ); - m_pBridgeImpl->addError( sMessage ); + OUStringBuffer sMessage; + sMessage.appendAscii( "unknown method type description for type" ); + sMessage.append( OUString( pITypeRef->pTypeName ) ); + sMessage.appendAscii( " (" ); + sMessage.append( (sal_Int32) nMethodId ); + sMessage.appendAscii( " )" ); + m_pBridgeImpl->addError( sMessage.makeStringAndClear() ); OSL_ENSURE( 0 , "unknown method type description" ); return sal_False; @@ -216,6 +217,9 @@ inline sal_Bool OReaderThread::getMemberTypeDescription( if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->aBase.eTypeClass ) { + // Note: pMapMemberIndexToFunctionIndex always contains the function + // index of the attribute getter! setter function index is getter index + // + 1. *ppAttributeType = (typelib_InterfaceAttributeTypeDescription *) pMemberType; *pbIsSetter = ! ( pInterfaceType->pMapMemberIndexToFunctionIndex[nMemberIndex] == nMethodId ); @@ -316,10 +320,11 @@ inline sal_Bool OReaderThread::readBlock( sal_Int32 *pnMessageCount ) // buffer too big // no exception can be thrown, because there is no thread id, which could be // used. -> terminate ! - OUString s( RTL_CONSTASCII_USTRINGPARAM( "Packet-size too big (" ) ); - s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nSize ); - s += OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) ); - m_pBridgeImpl->addError( s ); + OUStringBuffer s; + s.appendAscii( "Packet-size too big (" ); + s.append( (sal_Int64) (sal_uInt32 ) nSize ); + s.append( sal_Unicode( ')' ) ); + m_pBridgeImpl->addError( s.makeStringAndClear() ); OSL_ENSURE( 0 , "urp bridge: Packet-size too big" ); disposeEnvironment(); return sal_False; @@ -334,10 +339,11 @@ inline sal_Bool OReaderThread::readBlock( sal_Int32 *pnMessageCount ) // allocate the necessary memory if( ! m_unmarshal.setSize( nSize ) ) { - OUString s( RTL_CONSTASCII_USTRINGPARAM( "Packet-size too big, couln't allocate necessary memory (" ) ); - s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nSize ); - s += OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) ); - m_pBridgeImpl->addError( s ); + OUStringBuffer s; + s.appendAscii( "Packet-size too big, couln't allocate necessary memory (" ); + s.append( (sal_Int64) (sal_uInt32 ) nSize ); + s.append( sal_Unicode( ')' ) ); + m_pBridgeImpl->addError( s.makeStringAndClear() ); OSL_ENSURE( 0 , "urp bridge: messages size too large, terminating connection" ); return sal_False; } @@ -346,12 +352,13 @@ inline sal_Bool OReaderThread::readBlock( sal_Int32 *pnMessageCount ) if( nSize != nRead ) { - OUString s( RTL_CONSTASCII_USTRINGPARAM( "Unexpected connection closure, inconsistent packet (" ) ); - s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nSize ); - s += OUString( RTL_CONSTASCII_USTRINGPARAM( " asked, " ) ); - s += OUString::valueOf( (sal_Int64) (sal_uInt32 ) nRead ); - s += OUString( RTL_CONSTASCII_USTRINGPARAM( " got )" ) ); - m_pBridgeImpl->addError( s ); + OUStringBuffer s; + s.appendAscii( "Unexpected connection closure, inconsistent packet (" ); + s.append( (sal_Int64) (sal_uInt32 ) nSize ); + s.appendAscii( " asked, " ); + s.append( (sal_Int64) (sal_uInt32 ) nRead ); + s.appendAscii( " got )" ); + m_pBridgeImpl->addError( s.makeStringAndClear() ); // couldn't get the asked amount of bytes, quit // should only occur, when the environment has already been disposed OSL_ENSURE( m_pBridgeImpl->m_bDisposed , "urp bridge: inconsistent packet, terminating connection." ); @@ -524,9 +531,10 @@ void OReaderThread::run() } if( m_pBridgeImpl->m_lastInType.getTypeClass() != typelib_TypeClass_INTERFACE ) { - OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "interface type is not of typeclass interface (" )); - sMessage += OUString::valueOf( (sal_Int32) m_pBridgeImpl->m_lastInType.getTypeClass() ); - m_pBridgeImpl->addError( sMessage ); + OUStringBuffer sMessage; + sMessage.appendAscii( "interface type is not of typeclass interface (" ); + sMessage.append( (sal_Int32) m_pBridgeImpl->m_lastInType.getTypeClass() ); + m_pBridgeImpl->addError( sMessage.makeStringAndClear() ); OSL_ENSURE( 0 , "urp-bridge : not an interface type" ); disposeEnvironment(); break; @@ -597,9 +605,10 @@ void OReaderThread::run() *ppLastType ); if( !pInterfaceType ) { - OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "Couldn't retrieve type description for type " ) ); - sMessage += (*ppLastType)->pTypeName; - m_pBridgeImpl->addError( sMessage ); + OUStringBuffer sMessage; + sMessage.appendAscii( "Couldn't retrieve type description for type " ); + sMessage.append( OUString( (*ppLastType)->pTypeName ) ); + m_pBridgeImpl->addError( sMessage.makeStringAndClear() ); delete pMultiJob; pMultiJob = 0; disposeEnvironment(); diff --git a/bridges/test/inter_libs_exc/makefile.mk b/bridges/test/inter_libs_exc/makefile.mk index 484edc6702e8..f0a9225cc122 100644 --- a/bridges/test/inter_libs_exc/makefile.mk +++ b/bridges/test/inter_libs_exc/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.1 $ +# $Revision: 1.2 $ # -# last change: $Author: dbo $ $Date: 2002-08-19 12:49:42 $ +# last change: $Author: hr $ $Date: 2003-03-18 19:07:12 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -117,5 +117,5 @@ TYPES := -Tcom.sun.star.lang.IllegalArgumentException \ $(OUT)$/misc/inter_libs.flag : $(SOLARBINDIR)$/udkapi.rdb $(RM) $(OUT)$/misc/inter_libs.flag - +cppumaker $(CPPUMAKERFLAGS) -BUCR -O$(UNOUCROUT) $(TYPES) $(SOLARBINDIR)$/udkapi.rdb + +cppumaker $(CPPUMAKERFLAGS) -C -BUCR -O$(UNOUCROUT) $(TYPES) $(SOLARBINDIR)$/udkapi.rdb touch $(OUT)$/misc/inter_libs.flag diff --git a/bridges/test/java_uno/any/TestAny.java b/bridges/test/java_uno/any/TestAny.java new file mode 100644 index 000000000000..e9482fac614d --- /dev/null +++ b/bridges/test/java_uno/any/TestAny.java @@ -0,0 +1,2506 @@ +/************************************************************************* + * + * $RCSfile: TestAny.java,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:07:13 $ + * + * 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: 2002 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +package test.java_uno.anytest; + +import com.sun.star.uno.Any; +import com.sun.star.uno.Enum; +import com.sun.star.uno.Type; +import com.sun.star.uno.TypeClass; +import com.sun.star.uno.XInterface; +import java.lang.reflect.Array; + +final class TestAny { + public static boolean test(XTransport transport, boolean createTypes) { + boolean success = true; + + // Sanity check for com.sun.star.uno.Type: + success &= testType(void.class, TypeClass.VOID, "void"); + success &= testType(boolean.class, TypeClass.BOOLEAN, "boolean"); + success &= testType(byte.class, TypeClass.BYTE, "byte"); + success &= testType(short.class, TypeClass.SHORT, "short"); + success &= testType(int.class, TypeClass.LONG, "long"); + success &= testType(long.class, TypeClass.HYPER, "hyper"); + success &= testType(float.class, TypeClass.FLOAT, "float"); + success &= testType(double.class, TypeClass.DOUBLE, "double"); + success &= testType(char.class, TypeClass.CHAR, "char"); + success &= testType(String.class, TypeClass.STRING, "string"); + success &= testType(Type.class, TypeClass.TYPE, "type"); + success &= testType(Any.class, TypeClass.ANY, "any"); + success &= testType(boolean[].class, TypeClass.SEQUENCE, "[]boolean"); + success &= testType(byte[].class, TypeClass.SEQUENCE, "[]byte"); + success &= testType(short[].class, TypeClass.SEQUENCE, "[]short"); + success &= testType(int[].class, TypeClass.SEQUENCE, "[]long"); + success &= testType(long[].class, TypeClass.SEQUENCE, "[]hyper"); + success &= testType(float[].class, TypeClass.SEQUENCE, "[]float"); + success &= testType(double[].class, TypeClass.SEQUENCE, "[]double"); + success &= testType(char[].class, TypeClass.SEQUENCE, "[]char"); + success &= testType(String[].class, TypeClass.SEQUENCE, "[]string"); + success &= testType(Type[].class, TypeClass.SEQUENCE, "[]type"); + success &= testType(Any[].class, TypeClass.SEQUENCE, "[]any"); + success &= testType(Enum1[].class, TypeClass.SEQUENCE, + "[]" + Enum1.class.getName()); + success &= testType(BaseStruct[].class, TypeClass.SEQUENCE, + "[]" + BaseStruct.class.getName()); + success &= testType(DerivedStruct[].class, TypeClass.SEQUENCE, + "[]" + DerivedStruct.class.getName()); + success &= testType(XInterface[].class, TypeClass.SEQUENCE, + "[]" + XInterface.class.getName()); + success &= testType(BaseInterface[].class, TypeClass.SEQUENCE, + "[]" + BaseInterface.class.getName()); + success &= testType(DerivedInterface[].class, TypeClass.SEQUENCE, + "[]" + DerivedInterface.class.getName()); + success &= testType(boolean[][].class, TypeClass.SEQUENCE, + "[][]boolean"); + success &= testType(byte[][].class, TypeClass.SEQUENCE, "[][]byte"); + success &= testType(short[][].class, TypeClass.SEQUENCE, "[][]short"); + success &= testType(int[][].class, TypeClass.SEQUENCE, "[][]long"); + success &= testType(long[][].class, TypeClass.SEQUENCE, "[][]hyper"); + success &= testType(float[][].class, TypeClass.SEQUENCE, "[][]float"); + success &= testType(double[][].class, TypeClass.SEQUENCE, "[][]double"); + success &= testType(char[][].class, TypeClass.SEQUENCE, "[][]char"); + success &= testType(String[][].class, TypeClass.SEQUENCE, "[][]string"); + success &= testType(Type[][].class, TypeClass.SEQUENCE, "[][]type"); + success &= testType(Any[][].class, TypeClass.SEQUENCE, "[][]any"); + success &= testType(Enum1[][].class, TypeClass.SEQUENCE, + "[][]" + Enum1.class.getName()); + success &= testType(BaseStruct[][].class, TypeClass.SEQUENCE, + "[][]" + BaseStruct.class.getName()); + success &= testType(DerivedStruct[][].class, TypeClass.SEQUENCE, + "[][]" + DerivedStruct.class.getName()); + success &= testType(XInterface[][].class, TypeClass.SEQUENCE, + "[][]" + XInterface.class.getName()); + success &= testType(BaseInterface[][].class, TypeClass.SEQUENCE, + "[][]" + BaseInterface.class.getName()); + success &= testType(DerivedInterface[][].class, TypeClass.SEQUENCE, + "[][]" + DerivedInterface.class.getName()); + success &= testType(Enum1.class, TypeClass.ENUM, Enum1.class.getName()); + success &= testType(BaseStruct.class, TypeClass.STRUCT, + BaseStruct.class.getName()); + success &= testType(DerivedStruct.class, TypeClass.STRUCT, + DerivedStruct.class.getName()); + success &= testType(Exception.class, TypeClass.EXCEPTION, + Exception.class.getName()); + success &= testType(com.sun.star.uno.Exception.class, + TypeClass.EXCEPTION, + com.sun.star.uno.Exception.class.getName()); + success &= testType(BaseException.class, TypeClass.EXCEPTION, + BaseException.class.getName()); + success &= testType(DerivedException.class, TypeClass.EXCEPTION, + DerivedException.class.getName()); + success &= testType(RuntimeException.class, TypeClass.EXCEPTION, + RuntimeException.class.getName()); + success &= testType(com.sun.star.uno.RuntimeException.class, + TypeClass.EXCEPTION, + com.sun.star.uno.RuntimeException.class.getName()); + success &= testType(BaseRuntimeException.class, TypeClass.EXCEPTION, + BaseRuntimeException.class.getName()); + success &= testType(DerivedRuntimeException.class, + TypeClass.EXCEPTION, + DerivedRuntimeException.class.getName()); + success &= testType(XInterface.class, TypeClass.INTERFACE, + XInterface.class.getName()); + success &= testType(BaseInterface.class, TypeClass.INTERFACE, + BaseInterface.class.getName()); + success &= testType(DerivedInterface.class, TypeClass.INTERFACE, + DerivedInterface.class.getName()); + + // VOID: + success &= testMapAny(transport, Any.VOID, new CompareBoxed()); + + // BOOLEAN: + success &= testMapAny(transport, Boolean.FALSE, new CompareBoxed()); + success &= testMapAny(transport, Boolean.TRUE, new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.BOOLEAN, Boolean.FALSE), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.BOOLEAN, Boolean.TRUE), + new CompareUnboxed()); + + // BYTE: + success &= testMapAny(transport, new Byte((byte) -128), + new CompareBoxed()); + success &= testMapAny(transport, new Byte((byte) 0), + new CompareBoxed()); + success &= testMapAny(transport, new Byte((byte) 127), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.BYTE, new Byte((byte) -128)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.BYTE, new Byte((byte) 0)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.BYTE, new Byte((byte) 127)), + new CompareUnboxed()); + + // SHORT: + success &= testMapAny(transport, new Short((short) -32768), + new CompareBoxed()); + success &= testMapAny(transport, new Short((short) 0), + new CompareBoxed()); + success &= testMapAny(transport, new Short((short) 32767), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.SHORT, + new Short((short) -32768)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.SHORT, new Short((short) 0)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.SHORT, new Short((short) 32767)), + new CompareUnboxed()); + + // UNSIGNED SHORT: + success &= testMapAny(transport, + new Any(Type.UNSIGNED_SHORT, + new Short((short) 0)), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.UNSIGNED_SHORT, + new Short((short) -32768)), + new CompareBoxed()); + + // LONG: + success &= testMapAny(transport, new Integer(-2147483648), + new CompareBoxed()); + success &= testMapAny(transport, new Integer(0), + new CompareBoxed()); + success &= testMapAny(transport, new Integer(2147483647), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.LONG, new Integer(-2147483648)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.LONG, new Integer(0)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.LONG, new Integer(2147483647)), + new CompareUnboxed()); + + // UNSIGNED LONG: + success &= testMapAny(transport, + new Any(Type.UNSIGNED_LONG, new Integer(0)), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.UNSIGNED_LONG, + new Integer(-2147483648)), + new CompareBoxed()); + + // HYPER: + success &= testMapAny(transport, new Long(-9223372036854775808L), + new CompareBoxed()); + success &= testMapAny(transport, new Long(0L), new CompareBoxed()); + success &= testMapAny(transport, new Long(9223372036854775807L), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.HYPER, + new Long(-9223372036854775808L)), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.HYPER, new Long(0L)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.HYPER, + new Long(9223372036854775807L)), + new CompareUnboxed()); + + // UNSIGNED HYPER: + success &= testMapAny(transport, + new Any(Type.UNSIGNED_HYPER, new Long(0L)), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.UNSIGNED_HYPER, + new Long(-9223372036854775808L)), + new CompareBoxed()); + + // FLOAT: + success &= testMapAny(transport, new Float(Float.NEGATIVE_INFINITY), + new CompareBoxed()); + success &= testMapAny(transport, new Float(Float.MIN_VALUE), + new CompareBoxed()); + success &= testMapAny(transport, new Float(-0.0f), + new CompareBoxed()); + success &= testMapAny(transport, new Float(0.0f), + new CompareBoxed()); + success &= testMapAny(transport, new Float(Float.MAX_VALUE), + new CompareBoxed()); + success &= testMapAny(transport, new Float(Float.POSITIVE_INFINITY), + new CompareBoxed()); + success &= testMapAny(transport, new Float(Float.NaN), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.FLOAT, + new Float(Float.NEGATIVE_INFINITY)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.FLOAT, + new Float(Float.MIN_VALUE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.FLOAT, new Float(-0.0f)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.FLOAT, new Float(0.0f)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.FLOAT, + new Float(Float.MAX_VALUE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.FLOAT, + new Float(Float.POSITIVE_INFINITY)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.FLOAT, new Float(Float.NaN)), + new CompareUnboxed()); + + // DOUBLE: + success &= testMapAny(transport, + new Double(Double.NEGATIVE_INFINITY), + new CompareBoxed()); + success &= testMapAny(transport, new Double(Double.MIN_VALUE), + new CompareBoxed()); + success &= testMapAny(transport, new Double(-0.0f), + new CompareBoxed()); + success &= testMapAny(transport, new Double(0.0f), + new CompareBoxed()); + success &= testMapAny(transport, new Double(Double.MAX_VALUE), + new CompareBoxed()); + success &= testMapAny(transport, + new Double(Double.POSITIVE_INFINITY), + new CompareBoxed()); + success &= testMapAny(transport, new Double(Double.NaN), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.DOUBLE, + new Double(Double.NEGATIVE_INFINITY)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.DOUBLE, + new Double(Double.MIN_VALUE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.DOUBLE, new Double(-0.0)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.DOUBLE, new Double(0.0)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.DOUBLE, + new Double(Double.MAX_VALUE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.DOUBLE, + new Double(Double.POSITIVE_INFINITY)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.DOUBLE, new Double(Double.NaN)), + new CompareUnboxed()); + + // CHAR: + success &= testMapAny(transport, new Character('\u0000'), + new CompareBoxed()); + success &= testMapAny(transport, new Character('\uDBFF'), + new CompareBoxed()); + success &= testMapAny(transport, new Character('\uFFFD'), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(Type.CHAR, new Character('\u0000')), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.CHAR, new Character('\uDBFF')), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.CHAR, new Character('\uFFFD')), + new CompareUnboxed()); + + // STRING: + success &= testMapAny(transport, "", new CompareBoxed()); + success &= testMapAny(transport, "\uD800\uDC00", + new CompareBoxed()); + success &= testMapAny(transport, "Test", new CompareBoxed()); + success &= testMapAny(transport, new Any(Type.STRING, ""), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.STRING, "\uD800\uDC00"), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.STRING, "Test"), + new CompareUnboxed()); + + // TYPE: + success &= testMapAny(transport, Type.VOID, new CompareBoxed()); + success &= testMapAny(transport, Type.BOOLEAN, new CompareBoxed()); + success &= testMapAny(transport, Type.BYTE, new CompareBoxed()); + success &= testMapAny(transport, Type.SHORT, new CompareBoxed()); + success &= testMapAny(transport, Type.UNSIGNED_SHORT, + new CompareBoxed()); + success &= testMapAny(transport, Type.LONG, new CompareBoxed()); + success &= testMapAny(transport, Type.UNSIGNED_LONG, + new CompareBoxed()); + success &= testMapAny(transport, Type.HYPER, new CompareBoxed()); + success &= testMapAny(transport, Type.UNSIGNED_HYPER, + new CompareBoxed()); + success &= testMapAny(transport, Type.FLOAT, new CompareBoxed()); + success &= testMapAny(transport, Type.DOUBLE, new CompareBoxed()); + success &= testMapAny(transport, Type.CHAR, new CompareBoxed()); + success &= testMapAny(transport, Type.STRING, new CompareBoxed()); + success &= testMapAny(transport, Type.TYPE, new CompareBoxed()); + success &= testMapAny(transport, Type.ANY, new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]boolean", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]byte", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]short", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]unsigned short", + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]long", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]unsigned long", + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]hyper", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]unsigned hyper", + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]float", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]double", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]char", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]string", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]type", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]any", TypeClass.SEQUENCE), + new CompareBoxed()); + if (createTypes) { + success &= testMapAny(transport, + new Type("[]" + Enum1.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]" + BaseStruct.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]" + DerivedStruct.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + } + success &= testMapAny(transport, + new Type("[]" + XInterface.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]" + BaseInterface.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[]" + + DerivedInterface.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]boolean", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]byte", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]short", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]unsigned short", + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]long", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]unsigned long", + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]hyper", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]unsigned hyper", + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]float", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]double", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]char", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]string", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]type", TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]any", TypeClass.SEQUENCE), + new CompareBoxed()); + if (createTypes) { + success &= testMapAny(transport, + new Type("[][]" + Enum1.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]" + BaseStruct.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]" + + DerivedStruct.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + } + success &= testMapAny(transport, + new Type("[][]" + XInterface.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]" + + BaseInterface.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type("[][]" + + DerivedInterface.class.getName(), + TypeClass.SEQUENCE), + new CompareBoxed()); + if (createTypes) { + success &= testMapAny(transport, new Type(Enum1.class.getName(), + TypeClass.ENUM), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(BaseStruct.class.getName(), + TypeClass.STRUCT), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(DerivedStruct.class.getName(), + TypeClass.STRUCT), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(Exception.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(BaseException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(DerivedException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(RuntimeException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(BaseRuntimeException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + success &= testMapAny(transport, + new Type( + DerivedRuntimeException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + } + success &= testMapAny(transport, + new Type( + com.sun.star.uno.Exception.class. + getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + if (createTypes) { + success &= testMapAny(transport, + new Type(BaseUnoException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(DerivedUnoException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + } + success &= testMapAny(transport, + new Type( + com.sun.star.uno.RuntimeException.class. + getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + if (createTypes) { + success &= testMapAny(transport, + new Type( + BaseUnoRuntimeException.class.getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + success &= testMapAny(transport, + new Type( + DerivedUnoRuntimeException.class. + getName(), + TypeClass.EXCEPTION), + new CompareBoxed()); + } + success &= testMapAny(transport, + new Type(XInterface.class.getName(), + TypeClass.INTERFACE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(BaseInterface.class.getName(), + TypeClass.INTERFACE), + new CompareBoxed()); + success &= testMapAny(transport, + new Type(DerivedInterface.class.getName(), + TypeClass.INTERFACE), + new CompareBoxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.VOID), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.BOOLEAN), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.BYTE), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.SHORT), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, Type.UNSIGNED_SHORT), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.LONG), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, Type.UNSIGNED_LONG), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.HYPER), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, Type.UNSIGNED_HYPER), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.FLOAT), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.DOUBLE), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.CHAR), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.STRING), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.TYPE), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(Type.TYPE, Type.ANY), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]boolean", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]byte", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]short", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]unsigned short", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]long", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]unsigned long", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]hyper", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]unsigned hyper", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]float", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]double", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]char", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]string", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]type", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]any", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + if (createTypes) { + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]" + Enum1.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]" + + BaseStruct.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + "[]" + + DerivedStruct.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + } + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[]" + + XInterface.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + "[]" + + BaseInterface.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + "[]" + + DerivedInterface.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]boolean", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]byte", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]short", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]unsigned short", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]long", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]unsigned long", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]hyper", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]unsigned hyper", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]float", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]double", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]char", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]string", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]type", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]any", + TypeClass.SEQUENCE)), + new CompareUnboxed()); + if (createTypes) { + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]" + + Enum1.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]" + + BaseStruct.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + "[][]" + + DerivedStruct.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + } + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type("[][]" + + XInterface.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + "[][]" + + BaseInterface.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + "[][]" + + DerivedInterface.class.getName(), + TypeClass.SEQUENCE)), + new CompareUnboxed()); + if (createTypes) { + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type(Enum1.class.getName(), + TypeClass.ENUM)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type(BaseStruct.class.getName(), + TypeClass.STRUCT)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + DerivedStruct.class.getName(), + TypeClass.STRUCT)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type(Exception.class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + BaseException.class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + DerivedException.class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + RuntimeException.class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + BaseRuntimeException.class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + DerivedRuntimeException.class. + getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + } + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + com.sun.star.uno.Exception.class. + getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + if (createTypes) { + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + BaseUnoException.class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + DerivedUnoException.class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + } + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + com.sun.star.uno.RuntimeException. + class.getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + if (createTypes) { + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + BaseUnoRuntimeException.class. + getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + Type.TYPE, + new Type( + DerivedUnoRuntimeException.class. + getName(), + TypeClass.EXCEPTION)), + new CompareUnboxed()); + } + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type(XInterface.class.getName(), + TypeClass.INTERFACE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + BaseInterface.class.getName(), + TypeClass.INTERFACE)), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(Type.TYPE, + new Type( + DerivedInterface.class.getName(), + TypeClass.INTERFACE)), + new CompareUnboxed()); + + // Sequence Types: + success &= testMapAny(transport, new boolean[] {}, + new CompareBoxed()); + success &= testMapAny(transport, new boolean[] { false, true }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(boolean[].class), + new boolean[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(boolean[].class), + new boolean[] { false, true }), + new CompareUnboxed()); + success &= testMapAny(transport, new byte[] {}, + new CompareBoxed()); + success &= testMapAny(transport, new byte[] { -128, 0, 127 }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(byte[].class), + new byte[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(byte[].class), + new byte[] { -128, 0, 127 }), + new CompareUnboxed()); + success &= testMapAny(transport, new short[] {}, + new CompareBoxed()); + success &= testMapAny(transport, new short[] { -32768, 0, 32767 }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(short[].class), + new short[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(short[].class), + new short[] { -32768, 0, 32767 }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type("[]unsigned short", + TypeClass.SEQUENCE), + new short[] {}), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type("[]unsigned short", + TypeClass.SEQUENCE), + new short[] { 0, -32768 }), + new CompareBoxed()); + success &= testMapAny(transport, new int[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new int[] { -2147483648, 0, 2147483647 }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(int[].class), + new int[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(int[].class), + new int[] { -2147483648, 0, + 2147483647 }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type("[]unsigned long", + TypeClass.SEQUENCE), + new int[] {}), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type("[]unsigned long", + TypeClass.SEQUENCE), + new int[] { 0, -2147483648 }), + new CompareBoxed()); + success &= testMapAny(transport, new long[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new long[] { -9223372036854775808L, 0L, + 9223372036854775807L }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(long[].class), + new long[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(long[].class), + new long[] { -9223372036854775808L, + 0L, + 9223372036854775807L }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type("[]unsigned hyper", + TypeClass.SEQUENCE), + new long[] {}), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type("[]unsigned hyper", + TypeClass.SEQUENCE), + new long[] { 0L, + -9223372036854775808L }), + new CompareBoxed()); + success &= testMapAny(transport, new float[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new float[] { Float.NEGATIVE_INFINITY, + Float.MIN_VALUE, -0.0f, 0.0f, + Float.MAX_VALUE, + Float.POSITIVE_INFINITY, + Float.NaN }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(float[].class), + new float[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(float[].class), + new float[] { Float.NEGATIVE_INFINITY, + Float.MIN_VALUE, -0.0f, + 0.0f, Float.MAX_VALUE, + Float.POSITIVE_INFINITY, + Float.NaN }), + new CompareUnboxed()); + success &= testMapAny(transport, new double[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new double[] { Double.NEGATIVE_INFINITY, + Double.MIN_VALUE, -0.0, 0.0, + Double.MAX_VALUE, + Double.POSITIVE_INFINITY, + Double.NaN }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(double[].class), + new double[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(double[].class), + new double[] { + Double.NEGATIVE_INFINITY, + Double.MIN_VALUE, -0.0, 0.0, + Double.MAX_VALUE, + Double.POSITIVE_INFINITY, + Double.NaN }), + new CompareUnboxed()); + success &= testMapAny(transport, new char[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new char[] { '\u0000', '\uDBFF', '\uFFFD' }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(char[].class), + new char[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + new Type(char[].class), + new char[] { '\u0000', '\uDBFF', + '\uFFFD' }), + new CompareUnboxed()); + success &= testMapAny(transport, new String[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new String[] { "", "\uD800\uDC00", "Test" }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(String[].class), + new String[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(String[].class), + new String[] { "", "\uD800\uDC00", + "Test" }), + new CompareUnboxed()); + success &= testMapAny(transport, new Type[] {}, new CompareBoxed()); + success &= testMapAny(transport, + new Type[] { + Type.VOID, + new Type(DerivedInterface.class.getName(), + TypeClass.INTERFACE) }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(Type[].class), + new Type[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + new Type(Type[].class), + new Type[] { + Type.VOID, + new Type( + DerivedInterface.class.getName(), + TypeClass.INTERFACE) }), + new CompareUnboxed()); + success &= testMapAny(transport, new Object[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new Object[] { Any.VOID, Boolean.FALSE }, + new CompareBoxed()); + success &= testMapAny(transport, + new Object[] { + Boolean.FALSE, + new Any(Type.BOOLEAN, Boolean.TRUE) }, + new CompareBoxed(true)); + success &= testMapAny(transport, + new Any(new Type(Any[].class), + new Object[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(Any[].class), + new Object[] { Any.VOID, + Boolean.FALSE }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(Any[].class), + new Object[] { + Boolean.FALSE, + new Any(Type.BOOLEAN, + Boolean.TRUE) }), + new CompareUnboxed(true)); + success &= testMapAny(transport, new Any[] {}, + new CompareSpecific(new Object[] {})); + success &= testMapAny(transport, + new Any[] { Any.VOID, + new Any(Type.BOOLEAN, + Boolean.TRUE) }, + new CompareSpecific( + new Object[] { Any.VOID, Boolean.TRUE })); + success &= testMapAny(transport, + new Any(new Type(Any[].class), new Any[] {}), + new CompareSpecific(new Object[] {})); + success &= testMapAny(transport, + new Any(new Type(Any[].class), + new Any[] { Any.VOID, + new Any(Type.BOOLEAN, + Boolean.TRUE) }), + new CompareSpecific( + new Object[] { Any.VOID, Boolean.TRUE })); + success &= testMapAny(transport, + new Any(new Type(Any[].class), + new Boolean[] {}), + new CompareSpecific(new Object[] {})); + success &= testMapAny(transport, + new Any(new Type(Any[].class), + new Boolean[] { Boolean.FALSE }), + new CompareSpecific( + new Object[] { Boolean.FALSE })); + if (createTypes) { + success &= testMapAny(transport, new Enum1[] {}, + new CompareBoxed()); + success &= testMapAny(transport, new Enum1[] { new Enum1(), + new Enum2() }, + new CompareSpecific( + new Enum1[] { new Enum1(), + new Enum1() })); + success &= testMapAny(transport, + new Any(new Type(Enum1[].class), + new Enum1[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(Enum1[].class), + new Enum1[] { new Enum1(), + new Enum2() }), + new CompareSpecific( + new Enum1[] { new Enum1(), + new Enum1() })); + success &= testMapAny(transport, + new Any(new Type(Enum1[].class), + new Enum2[] {}), + new CompareSpecific(new Enum1[] {})); + success &= testMapAny(transport, + new Any(new Type(Enum1[].class), + new Enum2[] { new Enum2() }), + new CompareSpecific( + new Enum1[] { new Enum1() })); + success &= testMapAny(transport, new BaseStruct[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new BaseStruct[] { new BaseStruct(), + new DerivedStruct() }, + new CompareSpecific( + new BaseStruct[] { new BaseStruct(), + new BaseStruct() })); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[].class), + new BaseStruct[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[].class), + new BaseStruct[] { + new BaseStruct(), + new DerivedStruct() }), + new CompareSpecific( + new BaseStruct[] { new BaseStruct(), + new BaseStruct() })); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[].class), + new DerivedStruct[] {}), + new CompareSpecific(new BaseStruct[] {})); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[].class), + new DerivedStruct[] { + new DerivedStruct() }), + new CompareSpecific( + new BaseStruct[] { new BaseStruct() })); + success &= testMapAny(transport, new DerivedStruct[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new DerivedStruct[] { new DerivedStruct() }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedStruct[].class), + new DerivedStruct[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedStruct[].class), + new DerivedStruct[] { + new DerivedStruct() }), + new CompareUnboxed()); + } + success &= testMapAny(transport, new XInterface[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new XInterface[] { + null, new XInterface() {}, + new BaseInterface() {}, + new DerivedInterface() {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new XInterface[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new XInterface[] { + null, new XInterface() {}, + new BaseInterface() {}, + new DerivedInterface() {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new Object[] {}), + new CompareSpecific(new XInterface[] {})); + { + XInterface if1 = new XInterface() {}; + XInterface if2 = new BaseInterface() {}; + XInterface if3 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new Object[] { null, if1, if2, + if3 }), + new CompareSpecific( + new XInterface[] { null, if1, if2, + if3 })); + } + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new BaseInterface[] {}), + new CompareSpecific(new XInterface[] {})); + { + BaseInterface if1 = new BaseInterface() {}; + BaseInterface if2 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new BaseInterface[] { null, if1, + if2 }), + new CompareSpecific( + new XInterface[] { null, if1, if2 })); + } + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new DerivedInterface[] {}), + new CompareSpecific(new XInterface[] {})); + { + DerivedInterface if1 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(XInterface[].class), + new DerivedInterface[] { null, + if1 }), + new CompareSpecific( + new XInterface[] { null, if1 })); + } + success &= testMapAny(transport, new BaseInterface[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new BaseInterface[] { + null, new BaseInterface() {}, + new DerivedInterface() {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface[].class), + new BaseInterface[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface[].class), + new BaseInterface[] { + null, new BaseInterface() {}, + new DerivedInterface() {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface[].class), + new DerivedInterface[] {}), + new CompareSpecific(new BaseInterface[] {})); + { + DerivedInterface if1 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(BaseInterface[].class), + new DerivedInterface[] { null, + if1 }), + new CompareSpecific( + new BaseInterface[] { null, if1 })); + } + success &= testMapAny(transport, new DerivedInterface[] {}, + new CompareBoxed()); + success &= testMapAny(transport, + new DerivedInterface[] { + null, new DerivedInterface() {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedInterface[].class), + new DerivedInterface[] {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedInterface[].class), + new DerivedInterface[] { + null, + new DerivedInterface() {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new boolean[][] { new boolean[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new boolean[][] { + new boolean[] { false, true } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(boolean[][].class), + new boolean[][] { new boolean[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(boolean[][].class), + new boolean[][] { + new boolean[] { false, true } }), + new CompareUnboxed()); + success &= testMapAny(transport, new byte[][] { new byte[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new byte[][] { new byte[] { -128, 0, 127 } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(byte[][].class), + new byte[][] { new byte[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(byte[][].class), + new byte[][] { + new byte[] { -128, 0, 127 } }), + new CompareUnboxed()); + success &= testMapAny(transport, new short[][] { new short[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new short[][] { + new short[] { -32768, 0, 32767 } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(short[][].class), + new short[][] { new short[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(short[][].class), + new short[][] { + new short[] { -32768, 0, + 32767 } }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type("[][]unsigned short", + TypeClass.SEQUENCE), + new short[][] { new short[] {} }), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type("[][]unsigned short", + TypeClass.SEQUENCE), + new short[][] { + new short[] { 0, -32768 } }), + new CompareBoxed()); + success &= testMapAny(transport, new int[][] { new int[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new int[][] { new int[] { -2147483648, 0, + 2147483647 } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(int[][].class), + new int[][] { new int[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(int[][].class), + new int[][] { + new int[] { -2147483648, 0, + 2147483647 } }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type("[][]unsigned long", + TypeClass.SEQUENCE), + new int[][] { new int[] {} }), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type("[][]unsigned long", + TypeClass.SEQUENCE), + new int[][] { + new int[] { 0, -2147483648 } }), + new CompareBoxed()); + success &= testMapAny(transport, new long[][] { new long[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new long[][] { + new long[] { -9223372036854775808L, 0L, + 9223372036854775807L } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(long[][].class), + new long[][] { new long[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(long[][].class), + new long[][] { + new long[] { + -9223372036854775808L, 0L, + 9223372036854775807L } }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type("[][]unsigned hyper", + TypeClass.SEQUENCE), + new long[][] { new long[] {} }), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type("[][]unsigned hyper", + TypeClass.SEQUENCE), + new long[][] { + new long[] { + 0L, + -9223372036854775808L } }), + new CompareBoxed()); + success &= testMapAny(transport, new float[][] { new float[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new float[][] { + new float[] { Float.NEGATIVE_INFINITY, + Float.MIN_VALUE, -0.0f, + 0.0f, Float.MAX_VALUE, + Float.POSITIVE_INFINITY, + Float.NaN } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(float[][].class), + new float[][] { new float[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(float[][].class), + new float[][] { + new float[] { + Float.NEGATIVE_INFINITY, + Float.MIN_VALUE, -0.0f, 0.0f, + Float.MAX_VALUE, + Float.POSITIVE_INFINITY, + Float.NaN } }), + new CompareUnboxed()); + success &= testMapAny(transport, new double[][] { new double[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new double[][] { + new double[] { Double.NEGATIVE_INFINITY, + Double.MIN_VALUE, -0.0, + 0.0, Double.MAX_VALUE, + Double.POSITIVE_INFINITY, + Double.NaN } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(double[][].class), + new double[][] { new double[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(double[][].class), + new double[][] { + new double[] { + Double.NEGATIVE_INFINITY, + Double.MIN_VALUE, -0.0, 0.0, + Double.MAX_VALUE, + Double.POSITIVE_INFINITY, + Double.NaN } }), + new CompareUnboxed()); + success &= testMapAny(transport, new char[][] { new char[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new char[][] { + new char[] { '\u0000', '\uDBFF', + '\uFFFD' } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(char[][].class), + new char[][] { new char[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + new Type(char[][].class), + new char[][] { + new char[] { '\u0000', '\uDBFF', + '\uFFFD' } }), + new CompareUnboxed()); + success &= testMapAny(transport, new String[][] { new String[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new String[][] { + new String[] { "", "\uD800\uDC00", + "Test" } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(String[][].class), + new String[][] { new String[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(String[][].class), + new String[][] { + new String[] { "", "\uD800\uDC00", + "Test" } }), + new CompareUnboxed()); + success &= testMapAny(transport, new Type[][] { new Type[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new Type[][] { + new Type[] { + Type.VOID, + new Type( + DerivedInterface.class.getName(), + TypeClass.INTERFACE) } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(Type[][].class), + new Type[][] { new Type[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + new Type(Type[][].class), + new Type[][] { + new Type[] { + Type.VOID, + new Type( + DerivedInterface.class. + getName(), + TypeClass.INTERFACE) } }), + new CompareUnboxed()); + success &= testMapAny(transport, new Object[][] { new Object[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new Object[][] { + new Object[] { Any.VOID, + Boolean.FALSE } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Object[][] { + new Object[] { + Boolean.FALSE, + new Any(Type.BOOLEAN, + Boolean.TRUE) } }, + new CompareBoxed(true)); + success &= testMapAny(transport, + new Any(new Type(Any[][].class), + new Object[][] { new Object[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(Any[][].class), + new Object[][] { + new Object[] { Any.VOID, + Boolean.FALSE } }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(Any[][].class), + new Object[][] { + new Object[] { + Boolean.FALSE, + new Any(Type.BOOLEAN, + Boolean.TRUE) } }), + new CompareUnboxed(true)); + success &= testMapAny(transport, new Any[][] { new Any[] {} }, + new CompareSpecific( + new Object[][] { new Object[] {} })); + success &= testMapAny(transport, + new Any[][] { + new Any[] { Any.VOID, + new Any(Type.BOOLEAN, + Boolean.TRUE) } }, + new CompareSpecific( + new Object[][] { + new Object[] { Any.VOID, + Boolean.TRUE } })); + success &= testMapAny(transport, + new Any(new Type(Any[][].class), + new Any[][] { new Any[] {} }), + new CompareSpecific( + new Object[][] { new Object[] {} })); + success &= testMapAny(transport, + new Any(new Type(Any[][].class), + new Any[][] { + new Any[] { + Any.VOID, + new Any(Type.BOOLEAN, + Boolean.TRUE) } }), + new CompareSpecific( + new Object[][] { + new Object[] { Any.VOID, + Boolean.TRUE } })); + success &= testMapAny(transport, + new Any(new Type(Any[][].class), + new Boolean[][] { new Boolean[] {} }), + new CompareSpecific( + new Object[][] { new Object[] {} })); + success &= testMapAny(transport, + new Any(new Type(Any[][].class), + new Boolean[][] { + new Boolean[] { + Boolean.FALSE } }), + new CompareSpecific( + new Object[][] { + new Object[] { Boolean.FALSE } })); + if (createTypes) { + success &= testMapAny(transport, new Enum1[][] { new Enum1[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new Enum1[][] { + new Enum1[] { new Enum1(), + new Enum2() } }, + new CompareSpecific( + new Enum1[][] { + new Enum1[] { new Enum1(), + new Enum1() } })); + success &= testMapAny(transport, + new Any(new Type(Enum1[][].class), + new Enum1[][] { new Enum1[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(Enum1[][].class), + new Enum1[][] { + new Enum1[] { new Enum1(), + new Enum2() } }), + new CompareSpecific( + new Enum1[][] { + new Enum1[] { new Enum1(), + new Enum1() } })); + success &= testMapAny(transport, + new Any(new Type(Enum1[][].class), + new Enum2[][] { new Enum2[] {} }), + new CompareSpecific( + new Enum1[][] { new Enum1[] {} })); + success &= testMapAny(transport, + new Any(new Type(Enum1[][].class), + new Enum2[][] { + new Enum2[] { new Enum2() } }), + new CompareSpecific( + new Enum1[][] { + new Enum1[] { new Enum1() } })); + success &= testMapAny(transport, + new BaseStruct[][] { new BaseStruct[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new BaseStruct[][] { + new BaseStruct[] { + new BaseStruct(), + new DerivedStruct() } }, + new CompareSpecific( + new BaseStruct[][] { + new BaseStruct[] { + new BaseStruct(), + new BaseStruct() } })); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[][].class), + new BaseStruct[][] { + new BaseStruct[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[][].class), + new BaseStruct[][] { + new BaseStruct[] { + new BaseStruct(), + new DerivedStruct() } }), + new CompareSpecific( + new BaseStruct[][] { + new BaseStruct[] { + new BaseStruct(), + new BaseStruct() } })); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[][].class), + new DerivedStruct[][] { + new DerivedStruct[] {} }), + new CompareSpecific( + new BaseStruct[][] { + new BaseStruct[] {} })); + success &= testMapAny(transport, + new Any(new Type(BaseStruct[][].class), + new DerivedStruct[][] { + new DerivedStruct[] { + new DerivedStruct() } }), + new CompareSpecific( + new BaseStruct[][] { + new BaseStruct[] { + new BaseStruct() } })); + success &= testMapAny(transport, + new DerivedStruct[][] { + new DerivedStruct[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new DerivedStruct[][] { + new DerivedStruct[] { + new DerivedStruct() } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedStruct[][].class), + new DerivedStruct[][] { + new DerivedStruct[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedStruct[][].class), + new DerivedStruct[][] { + new DerivedStruct[] { + new DerivedStruct() } }), + new CompareUnboxed()); + } + success &= testMapAny(transport, + new XInterface[][] { new XInterface[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new XInterface[][] { + new XInterface[] { + null, new XInterface() {}, + new BaseInterface() {}, + new DerivedInterface() {} } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface[][].class), + new XInterface[][] { + new XInterface[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + new Type(XInterface[][].class), + new XInterface[][] { + new XInterface[] { + null, new XInterface() {}, + new BaseInterface() {}, + new DerivedInterface() {} } }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface[][].class), + new Object[][] { new Object[] {} }), + new CompareSpecific( + new XInterface[][] { + new XInterface[] {} })); + { + XInterface if1 = new XInterface() {}; + XInterface if2 = new BaseInterface() {}; + XInterface if3 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(XInterface[][].class), + new Object[][] { + new Object[] { null, if1, if2, + if3 } }), + new CompareSpecific( + new XInterface[][] { + new XInterface[] { null, if1, if2, + if3 } })); + } + success &= testMapAny(transport, + new Any(new Type(XInterface[][].class), + new BaseInterface[][] { + new BaseInterface[] {} }), + new CompareSpecific( + new XInterface[][] { + new XInterface[] {} })); + { + BaseInterface if1 = new BaseInterface() {}; + BaseInterface if2 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(XInterface[][].class), + new BaseInterface[][] { + new BaseInterface[] { + null, if1, if2 } }), + new CompareSpecific( + new XInterface[][] { + new XInterface[] { + null, if1, if2 } })); + } + success &= testMapAny(transport, + new Any(new Type(XInterface[][].class), + new DerivedInterface[][] { + new DerivedInterface[] {} }), + new CompareSpecific( + new XInterface[][] { + new XInterface[] {} })); + { + DerivedInterface if1 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(XInterface[][].class), + new DerivedInterface[][] { + new DerivedInterface[] { + null, if1 } }), + new CompareSpecific( + new XInterface[][] { + new XInterface[] { + null, if1 } })); + } + success &= testMapAny(transport, + new BaseInterface[][] { + new BaseInterface[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new BaseInterface[][] { + new BaseInterface[] { + null, new BaseInterface() {}, + new DerivedInterface() {} } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface[][].class), + new BaseInterface[][] { + new BaseInterface[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + new Type(BaseInterface[][].class), + new BaseInterface[][] { + new BaseInterface[] { + null, new BaseInterface() {}, + new DerivedInterface() {} } }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface[][].class), + new DerivedInterface[][] { + new DerivedInterface[] {} }), + new CompareSpecific( + new BaseInterface[][] { + new BaseInterface[] {} })); + { + DerivedInterface if1 = new DerivedInterface() {}; + success &= testMapAny(transport, + new Any(new Type(BaseInterface[][].class), + new DerivedInterface[][] { + new DerivedInterface[] { + null, if1 } }), + new CompareSpecific( + new BaseInterface[][] { + new BaseInterface[] { + null, if1 } })); + } + success &= testMapAny(transport, + new DerivedInterface[][] { + new DerivedInterface[] {} }, + new CompareBoxed()); + success &= testMapAny(transport, + new DerivedInterface[][] { + new DerivedInterface[] { + null, new DerivedInterface() {} } }, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedInterface[][].class), + new DerivedInterface[][] { + new DerivedInterface[] {} }), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any( + new Type(DerivedInterface[][].class), + new DerivedInterface[][] { + new DerivedInterface[] { + null, + new DerivedInterface() {} } }), + new CompareUnboxed()); + + // Enum Types: + if (createTypes) { + success &= testMapAny(transport, new Enum1(), new CompareBoxed()); + success &= testMapAny(transport, new Any(new Type(Enum1.class), + new Enum1()), + new CompareUnboxed()); + success &= testMapAny(transport, new Any(new Type(Enum1.class), + new Enum2()), + new CompareSpecific(new Enum1())); + } + + // Struct Types: + if (createTypes) { + success &= testMapAny(transport, new BaseStruct(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseStruct.class), + new BaseStruct()), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseStruct.class), + new DerivedStruct()), + new CompareSpecific(new BaseStruct())); + success &= testMapAny(transport, new DerivedStruct(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedStruct.class), + new DerivedStruct()), + new CompareUnboxed()); + } + + // Exception Types: + if (createTypes) { + success &= testMapAny(transport, new Exception(), + new CompareClass(Exception.class)); + success &= testMapAny(transport, + new Any(new Type(Exception.class), + new Exception()), + new CompareClass(Exception.class)); + success &= testMapAny(transport, + new Any(new Type(Exception.class), + new BaseException()), + new CompareClass(Exception.class)); + success &= testMapAny(transport, + new Any(new Type(Exception.class), + new DerivedException()), + new CompareClass(Exception.class)); + success &= testMapAny(transport, + new Any(new Type(Exception.class), + new com.sun.star.uno.Exception()), + new CompareClass(Exception.class)); + success &= testMapAny(transport, + new Any(new Type(Exception.class), + new BaseUnoException()), + new CompareClass(Exception.class)); + success &= testMapAny(transport, + new Any(new Type(Exception.class), + new DerivedUnoException()), + new CompareClass(Exception.class)); + success &= testMapAny(transport, new BaseException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseException.class), + new BaseException()), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseException.class), + new DerivedException()), + new CompareSpecific(new BaseException())); + success &= testMapAny(transport, new DerivedException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedException.class), + new DerivedException()), + new CompareUnboxed()); + success &= testMapAny(transport, new RuntimeException(), + new CompareClass(RuntimeException.class)); + success &= testMapAny(transport, + new Any(new Type(RuntimeException.class), + new RuntimeException()), + new CompareClass(RuntimeException.class)); + success &= testMapAny(transport, + new Any(new Type(RuntimeException.class), + new BaseRuntimeException()), + new CompareClass(RuntimeException.class)); + success &= testMapAny(transport, + new Any(new Type(RuntimeException.class), + new DerivedRuntimeException()), + new CompareClass(RuntimeException.class)); + success &= testMapAny(transport, + new Any( + new Type(RuntimeException.class), + new com.sun.star.uno.RuntimeException()), + new CompareClass(RuntimeException.class)); + success &= testMapAny(transport, + new Any(new Type(RuntimeException.class), + new BaseUnoRuntimeException()), + new CompareClass(RuntimeException.class)); + success &= testMapAny(transport, + new Any(new Type(RuntimeException.class), + new DerivedUnoRuntimeException()), + new CompareClass(RuntimeException.class)); + success &= testMapAny(transport, new BaseRuntimeException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseRuntimeException.class), + new BaseRuntimeException()), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseRuntimeException.class), + new DerivedRuntimeException()), + new CompareSpecific( + new BaseRuntimeException())); + success &= testMapAny(transport, new DerivedRuntimeException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type( + DerivedRuntimeException.class), + new DerivedRuntimeException()), + new CompareUnboxed()); + } + success &= testMapAny(transport, new com.sun.star.uno.Exception(), + new CompareClass( + com.sun.star.uno.Exception.class)); + success &= testMapAny(transport, + new Any(new Type( + com.sun.star.uno.Exception.class), + new com.sun.star.uno.Exception()), + new CompareClass( + com.sun.star.uno.Exception.class)); + success &= testMapAny(transport, + new Any(new Type( + com.sun.star.uno.Exception.class), + new BaseUnoException()), + new CompareClass( + com.sun.star.uno.Exception.class)); + success &= testMapAny(transport, + new Any(new Type( + com.sun.star.uno.Exception.class), + new DerivedUnoException()), + new CompareClass( + com.sun.star.uno.Exception.class)); + if (createTypes) { + success &= testMapAny(transport, new BaseUnoException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseUnoException.class), + new BaseUnoException()), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseUnoException.class), + new DerivedUnoException()), + new CompareSpecific(new BaseUnoException())); + success &= testMapAny(transport, new DerivedUnoException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedUnoException.class), + new DerivedUnoException()), + new CompareUnboxed()); + } + success &= testMapAny(transport, + new com.sun.star.uno.RuntimeException(), + new CompareClass( + com.sun.star.uno.RuntimeException.class)); + success &= testMapAny(transport, + new Any( + new Type( + com.sun.star.uno.RuntimeException. + class), + new com.sun.star.uno.RuntimeException()), + new CompareClass( + com.sun.star.uno.RuntimeException.class)); + success &= testMapAny(transport, + new Any( + new Type( + com.sun.star.uno.RuntimeException. + class), + new BaseUnoRuntimeException()), + new CompareClass( + com.sun.star.uno.RuntimeException.class)); + success &= testMapAny(transport, + new Any( + new Type( + com.sun.star.uno.RuntimeException. + class), + new DerivedUnoRuntimeException()), + new CompareClass( + com.sun.star.uno.RuntimeException.class)); + if (createTypes) { + success &= testMapAny(transport, new BaseUnoRuntimeException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type( + BaseUnoRuntimeException.class), + new BaseUnoRuntimeException()), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type( + BaseUnoRuntimeException.class), + new DerivedUnoRuntimeException()), + new CompareSpecific( + new BaseUnoRuntimeException())); + success &= testMapAny(transport, new DerivedUnoRuntimeException(), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type( + DerivedUnoRuntimeException.class), + new DerivedUnoRuntimeException()), + new CompareUnboxed()); + } + + // Interface Types: + success &= testMapAny(transport, null, new CompareBoxed()); + success &= testMapAny(transport, new XInterface() {}, + new CompareBoxed()); + success &= testMapAny(transport, new BaseInterface() {}, + new CompareBoxed()); + success &= testMapAny(transport, new DerivedInterface() {}, + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface.class), null), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface.class), + new XInterface() {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface.class), + new BaseInterface() {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(XInterface.class), + new DerivedInterface() {}), + new CompareUnboxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface.class), null), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface.class), + new BaseInterface() {}), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(BaseInterface.class), + new DerivedInterface() {}), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedInterface.class), + null), + new CompareBoxed()); + success &= testMapAny(transport, + new Any(new Type(DerivedInterface.class), + new DerivedInterface() {}), + new CompareBoxed()); + + return success; + } + + private TestAny() {} // do not instantiate + + private static boolean testType(Class zclass, TypeClass tclass, + String tname) { + Type t1 = new Type(zclass); + Type t2 = new Type(tname, tclass); + boolean ok = true; + if (t1.getTypeClass() != tclass) { + ok = false; + System.out.println("BAD Type(" + zclass + ").getTypeClass() = " + + t1.getTypeClass() + " != " + tclass); + } + if (!t1.getTypeName().equals(tname)) { + ok = false; + System.out.println("BAD Type(" + zclass + ").getTypeName() = " + + t1.getTypeName() + " != " + tname); + } + if (!t1.equals(t2)) { + ok = false; + System.out.println("BAD Type(" + zclass + ") != Type(" + tname + + ", " + tclass + ")"); + } + return ok; + } + + private static boolean testMapAny(XTransport transport, Object any, + Compare compare) { + Object any2 = transport.mapAny(any); + boolean eq = compare.equal(any, any2); + if (!eq) { + System.out.println("BAD mapAny(" + any + ") -> " + any2); + } + return eq; + } + + private static abstract class Compare { + public abstract boolean equal(Object o1, Object o2); + } + + private static final class CompareBoxed extends Compare { + public CompareBoxed() { + this(false); + } + + public CompareBoxed(boolean unboxInner) { + this.unboxInner = unboxInner; + } + + public boolean equal(Object o1, Object o2) { + if (o1 instanceof Any) { + return o2 instanceof Any + && ((Any) o1).getType().equals(((Any) o2).getType()) + && equalValues(((Any) o1).getObject(), + ((Any) o2).getObject()); + } else { + return equalValues(o1, o2); + } + } + + private boolean equalValues(Object o1, Object o2) { + if (o1 == null) { + return o2 == null; + } else if (o1.getClass().isArray()) { + if (!(o2 != null && o1.getClass() == o2.getClass() + && Array.getLength(o1) == Array.getLength(o2))) { + return false; + } + for (int i = 0; i < Array.getLength(o1); ++i) { + Object oo1 = Array.get(o1, i); + if (unboxInner && oo1 instanceof Any) { + oo1 = ((Any) oo1).getObject(); + } + if (!equal(oo1, Array.get(o2, i))) { + return false; + } + } + return true; + } else { + return o1.equals(o2); + } + } + + private final boolean unboxInner; + } + + private static final class CompareUnboxed extends Compare { + public CompareUnboxed() { + this(false); + } + + public CompareUnboxed(boolean unboxInner) { + this.unboxInner = unboxInner; + } + + public boolean equal(Object o1, Object o2) { + return new CompareBoxed(unboxInner).equal(((Any) o1).getObject(), + o2); + } + + private final boolean unboxInner; + } + + private static final class CompareSpecific extends Compare { + public CompareSpecific(Object specific) { + this.specific = specific; + } + + public boolean equal(Object o1, Object o2) { + return new CompareBoxed().equal(specific, o2); + } + + private final Object specific; + } + + private static final class CompareClass extends Compare { + public CompareClass(Class clazz) { + this.clazz = clazz; + } + + public boolean equal(Object o1, Object o2) { + return o2 != null && o2.getClass() == clazz; + } + + private final Class clazz; + } + + public static class Enum1 extends Enum { + public Enum1() { + super(0); + } + + public static Enum1 fromInt(int value) { + return new Enum1(); + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == Enum1.class; + } + } + + public static class Enum2 extends Enum1 { + public boolean equals(Object obj) { + return obj != null && obj.getClass() == Enum2.class; + } + } + + public static class BaseStruct { + public boolean equals(Object obj) { + return obj != null && obj.getClass() == BaseStruct.class; + } + } + + public static class DerivedStruct extends BaseStruct { + public boolean equals(Object obj) { + return obj != null && obj.getClass() == DerivedStruct.class; + } + } + + public static class BaseException extends Exception { + public BaseException() {} + + public BaseException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == BaseException.class; + } + } + + public static class DerivedException extends BaseException { + public DerivedException() {} + + public DerivedException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == DerivedException.class; + } + } + + public static class BaseRuntimeException extends RuntimeException { + public BaseRuntimeException() {} + + public BaseRuntimeException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == BaseRuntimeException.class; + } + } + + public static class DerivedRuntimeException extends BaseRuntimeException { + public DerivedRuntimeException() {} + + public DerivedRuntimeException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null + && obj.getClass() == DerivedRuntimeException.class; + } + } + + public static class BaseUnoException extends com.sun.star.uno.Exception { + public BaseUnoException() {} + + public BaseUnoException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == BaseUnoException.class; + } + } + + public static class DerivedUnoException extends BaseUnoException { + public DerivedUnoException() {} + + public DerivedUnoException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null && obj.getClass() == DerivedUnoException.class; + } + } + + public static class BaseUnoRuntimeException + extends com.sun.star.uno.RuntimeException + { + public BaseUnoRuntimeException() {} + + public BaseUnoRuntimeException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null + && obj.getClass() == BaseUnoRuntimeException.class; + } + } + + public static class DerivedUnoRuntimeException + extends BaseUnoRuntimeException + { + public DerivedUnoRuntimeException() {} + + public DerivedUnoRuntimeException(String message) { + super(message); + } + + public boolean equals(Object obj) { + return obj != null + && obj.getClass() == DerivedUnoRuntimeException.class; + } + } +} diff --git a/bridges/test/java_uno/any/TestJni.java b/bridges/test/java_uno/any/TestJni.java new file mode 100644 index 000000000000..937147d919ec --- /dev/null +++ b/bridges/test/java_uno/any/TestJni.java @@ -0,0 +1,81 @@ +/************************************************************************* + * + * $RCSfile: TestJni.java,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:07:15 $ + * + * 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: 2002 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +package test.java_uno.anytest; + +public class TestJni +{ + static { System.loadLibrary( "test_javauno_any" ); } + private static native XTransport create_jni_transport(); + + public static void main( String args [] ) + { + if (TestAny.test( create_jni_transport(), false )) + { + System.out.println( "jni any test succeeded." ); + } + else + { + System.err.println( "jni any test failed!" ); + System.exit( 1 ); + } + } +} diff --git a/bridges/test/java_uno/any/TestRemote.java b/bridges/test/java_uno/any/TestRemote.java new file mode 100644 index 000000000000..29a408d990d1 --- /dev/null +++ b/bridges/test/java_uno/any/TestRemote.java @@ -0,0 +1,107 @@ +/************************************************************************* + * + * $RCSfile: TestRemote.java,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:07:16 $ + * + * 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: 2002 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +package test.java_uno.anytest; + +import com.sun.star.bridge.XBridge; +import com.sun.star.bridge.XInstanceProvider; +import com.sun.star.lang.XComponent; +import com.sun.star.uno.UnoRuntime; + +public final class TestRemote { + public static void main(String[] args) throws Exception { + TestBed t = new TestBed(); + t.setProvider(new Provider(t)); + t.execute(Client.class, 0); + } + + public static final class Client extends TestBed.Client { + public static void main(String[] args) { + new Client().execute(); + } + + protected boolean run(XBridge bridge) throws Throwable { + XTransport transport = (XTransport) UnoRuntime.queryInterface( + XTransport.class, bridge.getInstance("Transport")); + boolean success = TestAny.test(transport, true); + ((XComponent) UnoRuntime.queryInterface(XComponent.class, bridge)). + dispose(); + return success; + } + } + + private static final class Provider implements XInstanceProvider { + public Provider(TestBed testBed) { + this.testBed = testBed; + } + + public Object getInstance(String instanceName) { + testBed.serverDone(true); + return new XTransport() { + public Object mapAny(Object any) { + return any; + } + }; + } + + private final TestBed testBed; + } +} diff --git a/bridges/test/java_uno/any/makefile.mk b/bridges/test/java_uno/any/makefile.mk new file mode 100644 index 000000000000..7868115e4e47 --- /dev/null +++ b/bridges/test/java_uno/any/makefile.mk @@ -0,0 +1,154 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.2 $ +# +# last change: $Author: hr $ $Date: 2003-03-18 19:07:17 $ +# +# 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: 2002 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +#************************************************************************* + +PRJ = ..$/..$/.. +PRJNAME = bridges +TARGET = test_javauno_any + +PACKAGE = test$/java_uno$/anytest + +.INCLUDE: settings.mk + +.IF "$(GUI)" == "WNT" +GIVE_EXEC_RIGHTS = @echo +.ELSE +GIVE_EXEC_RIGHTS = chmod +x +.ENDIF + +JAVAFLAGS += -sourcepath $(OUT)$/misc$/java$/test + +JAVAFILES = \ + $(subst,$(CLASSDIR)$/$(PACKAGE)$/, $(subst,.class,.java $(JAVACLASSFILES))) + +EXEC_CLASSPATH_TMP = \ + $(foreach,i,$(JARFILES) $(SOLARBINDIR)$/$i)$(PATH_SEPERATOR)$(XCLASSPATH) +EXEC_CLASSPATH = \ + $(strip $(subst,!,$(PATH_SEPERATOR) $(EXEC_CLASSPATH_TMP:s/ /!/))) + +JARFILES = juh.jar jurt.jar ridl.jar sandbox.jar +JAVACLASSFILES = \ + $(CLASSDIR)$/$(PACKAGE)$/TestAny.class \ + $(CLASSDIR)$/$(PACKAGE)$/TestBed.class \ + $(CLASSDIR)$/$(PACKAGE)$/TestRemote.class \ + $(CLASSDIR)$/$(PACKAGE)$/TestJni.class + +#-------------------------------------------------- + +USE_DEFFILE = TRUE +ENABLE_EXCEPTIONS = TRUE +INCPRE += $(OUT)$/inc$/test + +.IF "$(debug)" != "" +.IF "$(COM)" == "MSC" +CFLAGS += -Ob0 +.ENDIF +.ENDIF + +SLOFILES= \ + $(SLO)$/transport.obj + +SHL1TARGET=$(TARGET) + +SHL1STDLIBS= \ + $(CPPUHELPERLIB) \ + $(SALHELPERLIB) \ + $(JVMACCESSLIB) \ + $(CPPULIB) \ + $(SALLIB) + +SHL1VERSIONMAP=$(TARGET).map +SHL1IMPLIB=i$(TARGET) +SHL1LIBS=$(SLB)$/$(TARGET).lib +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +.INCLUDE: target.mk + +#-------------------------------------------------- + +$(SLOFILES) : $(MISC)$/gen_files.flag +$(JAVACLASSFILES) : $(MISC)$/gen_files.flag + +ALLTAR : \ + $(OUT)$/bin$/TestRemote$(SCRIPTEXT) \ + $(OUT)$/bin$/TestJni$(SCRIPTEXT) + +$(OUT)$/bin$/TestRemote$(SCRIPTEXT) : $(JAVACLASSFILES) + -rm -f $@ + +echo java -classpath .$(PATH_SEPERATOR)..$/class$(PATH_SEPERATOR)$(EXEC_CLASSPATH) \ + test.java_uno.anytest.TestRemote > $@ + $(GIVE_EXEC_RIGHTS) $@ + +$(OUT)$/bin$/TestJni$(SCRIPTEXT) : $(JAVACLASSFILES) + -rm -f $@ + +echo java -classpath .$(PATH_SEPERATOR)..$/class$(PATH_SEPERATOR)$(EXEC_CLASSPATH) \ + test.java_uno.anytest.TestJni >> $@ + $(GIVE_EXEC_RIGHTS) $@ + +$(BIN)$/test_java_uno_anytest.rdb : types.idl + +idlc -I$(PRJ) -I$(SOLARIDLDIR) -O$(BIN) $? + +regmerge $@ /UCR $(BIN)$/{$(?:f:s/.idl/.urd/)} + +$(MISC)$/gen_files.flag : $(BIN)$/test_java_uno_anytest.rdb + +cppumaker -C -BUCR -O $(OUT)$/inc$/test -X $(SOLARBINDIR)$/udkapi.rdb $? + +cppumaker -C -BUCR -O $(OUT)$/inc$/test -T com.sun.star.uno.XInterface $(SOLARBINDIR)$/udkapi.rdb + +javamaker -nD -BUCR -O $(OUT)$/misc$/java$/test -X $(SOLARBINDIR)$/udkapi.rdb $? + +$(TOUCH) $@ diff --git a/bridges/test/java_uno/any/test_javauno_any.map b/bridges/test/java_uno/any/test_javauno_any.map new file mode 100644 index 000000000000..4959db8fccc8 --- /dev/null +++ b/bridges/test/java_uno/any/test_javauno_any.map @@ -0,0 +1,6 @@ +UDK_3.1 { + global: + Java_test_java_1uno_anytest_TestJni_create_1jni_1transport; + local: + *; +}; diff --git a/bridges/test/java_uno/any/transport.cxx b/bridges/test/java_uno/any/transport.cxx new file mode 100644 index 000000000000..a5125e865297 --- /dev/null +++ b/bridges/test/java_uno/any/transport.cxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * $RCSfile: transport.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:07:19 $ + * + * 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: 2002 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "jni.h" + +#include "uno/mapping.hxx" +#include "uno/environment.hxx" +#include "jvmaccess/virtualmachine.hxx" +#include "cppuhelper/implbase1.hxx" + +#include "test/java_uno/anytest/XTransport.hpp" +#include "test/java_uno/anytest/DerivedInterface.hpp" + + +using namespace ::com::sun::star::uno; +using ::test::java_uno::anytest::XTransport; +using ::rtl::OUString; + +namespace +{ +//================================================================================================== +class Transport : public ::cppu::WeakImplHelper1< XTransport > +{ +public: + virtual Any SAL_CALL mapAny( Any const & any ) + throw (RuntimeException); +}; +//__________________________________________________________________________________________________ +Any Transport::mapAny( Any const & any ) + throw (RuntimeException) +{ + return any; +} +} + +//################################################################################################## +extern "C" JNIEXPORT jobject JNICALL Java_test_java_1uno_anytest_TestJni_create_1jni_1transport( + JNIEnv * jni_env, jclass ) + SAL_THROW_EXTERN_C() +{ + // publish some idl types + ::getCppuType( (Reference< XTransport > const *)0 ); + ::getCppuType( (Reference< ::test::java_uno::anytest::DerivedInterface > const *)0 ); + + Reference< XTransport > xRet( new Transport() ); + + // get java vm + JavaVM * java_vm; + OSL_VERIFY( 0 == jni_env->GetJavaVM( &java_vm ) ); + // create jvmaccess vm + ::rtl::Reference< ::jvmaccess::VirtualMachine > vm( + new ::jvmaccess::VirtualMachine( java_vm, JNI_VERSION_1_2, false, jni_env ) ); + // create uno envs + OUString java_name( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_JAVA) ); + OUString cpp_name( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ); + Environment java_env, cpp_env; + uno_getEnvironment( (uno_Environment **)&java_env, java_name.pData, vm.get() ); + OSL_ASSERT( java_env.is() ); + uno_getEnvironment( (uno_Environment **)&cpp_env, cpp_name.pData, 0 ); + OSL_ASSERT( cpp_env.is() ); + + // map interface + Mapping mapping( cpp_env.get(), java_env.get() ); + OSL_ASSERT( mapping.is() ); + jobject jo_global = (jobject)mapping.mapInterface( xRet.get(), ::getCppuType( &xRet ) ); + OSL_ASSERT( 0 != jo_global ); + + // return + jobject jo_ret = jni_env->NewLocalRef( jo_global ); + jni_env->DeleteGlobalRef( jo_global ); + return jo_ret; +} diff --git a/bridges/test/java_uno/any/types.idl b/bridges/test/java_uno/any/types.idl new file mode 100644 index 000000000000..61efe9d12e2d --- /dev/null +++ b/bridges/test/java_uno/any/types.idl @@ -0,0 +1,76 @@ +/************************************************************************* + * + * $RCSfile: types.idl,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2003-03-18 19:07:19 $ + * + * 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: 2002 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include <com/sun/star/uno/XInterface.idl> + + +module test { module java_uno { module anytest { + +interface XTransport : com::sun::star::uno::XInterface +{ + any mapAny([in] any a); +}; + +interface BaseInterface : com::sun::star::uno::XInterface {}; + +interface DerivedInterface : BaseInterface {}; + +}; }; }; diff --git a/bridges/test/makefile.mk b/bridges/test/makefile.mk index d8173faa9b5d..745b699eff9d 100644 --- a/bridges/test/makefile.mk +++ b/bridges/test/makefile.mk @@ -2,9 +2,9 @@ # # $RCSfile: makefile.mk,v $ # -# $Revision: 1.5 $ +# $Revision: 1.6 $ # -# last change: $Author: jbu $ $Date: 2001-05-29 07:09:02 $ +# last change: $Author: hr $ $Date: 2003-03-18 19:07:09 $ # # The Contents of this file are made available subject to the terms of # either of the following licenses @@ -77,7 +77,7 @@ NO_BSYMBOLIC=TRUE # --- Files -------------------------------------------------------- ALLIDLFILES = test_bridge.idl -#CPPUMAKERFLAGS += -C +CPPUMAKERFLAGS += -C UNOUCRDEP=$(SOLARBINDIR)$/udkapi.rdb diff --git a/bridges/test/testclient.cxx b/bridges/test/testclient.cxx index 05dbf4659575..9f464df4846f 100644 --- a/bridges/test/testclient.cxx +++ b/bridges/test/testclient.cxx @@ -2,9 +2,9 @@ * * $RCSfile: testclient.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: jbu $ $Date: 2002-04-18 10:09:22 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:09 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -171,7 +171,7 @@ int main( int argc, char *argv[] ) "usage : testclient [-r] connectionstring\n" " -r reverse call me test (server calls client)" ); - return 1; + return 0; } OUString sConnectionString; diff --git a/bridges/test/testcomp.cxx b/bridges/test/testcomp.cxx index 356618242543..78bfb1b41d8b 100644 --- a/bridges/test/testcomp.cxx +++ b/bridges/test/testcomp.cxx @@ -2,9 +2,9 @@ * * $RCSfile: testcomp.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: jbu $ $Date: 2002-04-18 10:09:22 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:10 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -125,7 +125,7 @@ void parseCommandLine( char *argv[] , } } -Any OInstanceProvider::queryInterface( const Type & aType ) throw ( RuntimeException ) +Any OInstanceProvider::queryInterface( const Type & aType ) { Any a = ::cppu::queryInterface( aType , SAL_STATIC_CAST( XInstanceProvider * , this ) ); @@ -192,9 +192,9 @@ public: } return aRet; } - virtual void SAL_CALL acquire() throw() + virtual void SAL_CALL acquire() throw(::com::sun::star::uno::RuntimeException) { osl_incrementInterlockedCount( &_nRef ); } - virtual void SAL_CALL release() throw() + virtual void SAL_CALL release() throw(::com::sun::star::uno::RuntimeException) { if (! osl_decrementInterlockedCount( &_nRef )) delete this; } // XServiceInfo @@ -325,7 +325,7 @@ Sequence< OUString > ServiceImpl::getSupportedServiceNames() * *****************/ -Any OCallMe::queryInterface( const Type & aType ) throw ( RuntimeException ) +Any OCallMe::queryInterface( const Type & aType ) { Any a = ::cppu::queryInterface( aType, SAL_STATIC_CAST( XCallMe * , this ) ); @@ -421,7 +421,7 @@ void OCallMe::callAgain( const Reference< ::test::XCallMe >& callAgain, * OInterfaceTest * *******************/ -Any OInterfaceTest::queryInterface( const Type & aType ) throw ( RuntimeException ) +Any OInterfaceTest::queryInterface( const Type & aType ) { Any a = ::cppu::queryInterface( aType, SAL_STATIC_CAST( XInterfaceTest * , this ) ); @@ -473,7 +473,7 @@ void OInterfaceTest::call() } -Any OTestFactory::queryInterface( const Type & aType ) throw ( RuntimeException ) +Any OTestFactory::queryInterface( const Type & aType ) { Any a = ::cppu::queryInterface( aType, SAL_STATIC_CAST( XTestFactory * , this ) ); @@ -500,6 +500,42 @@ Reference< ::test::XInterfaceTest > SAL_CALL OTestFactory::createInterfaceTest( +/******************************************************** + * + ********************************************************/ +/*Any OConnectCallback::queryInterface( const Type & aType ) +{ + Any a = ::cppu::queryInterface( aType, + SAL_STATIC_CAST( XConnectCallback * , this ) ); + if( a.hasValue() ) + { + return a; + } + return OWeakObject::queryInterface( aType ); +} + + +void SAL_CALL OConnectCallback::attemptConnect( + const Reference< XConnectionServerSide >& connection ) + throw(SecurityException, ::com::sun::star::uno::RuntimeException) +{ + // TODO + // user verification + if( L"bad guy" == connection->getUser() && + L"secret" == connection->getPassword() ) + { + Reference< XInterface > rInterface( + ( XInterface * ) (::cppu::OWeakObject *) new OTestFactory() ); + connection->provideRemoteObject( rInterface ); + } + else + { + throw SecurityException(); + } +} + +*/ + // class OInstanceProvider : // public ::cppu::OWeakObject, @@ -515,6 +551,7 @@ Reference< ::test::XInterfaceTest > SAL_CALL OTestFactory::createInterfaceTest( // void SAL_CALL release() { OWeakObject::release(); } // public: +// // XConnectCallback // virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL // getInstance( const ::rtl::OUString& sObjectName ) // throw( ::com::sun::star::container::NoSuchElementException, diff --git a/bridges/test/testcomp.h b/bridges/test/testcomp.h index f525b797dcc2..d042259c8248 100644 --- a/bridges/test/testcomp.h +++ b/bridges/test/testcomp.h @@ -2,9 +2,9 @@ * * $RCSfile: testcomp.h,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: jbu $ $Date: 2002-04-18 10:09:22 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:10 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -87,9 +87,9 @@ public: public: // XInterface - Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType) throw ( ::com::sun::star::uno::RuntimeException ); - void SAL_CALL acquire() throw() { OWeakObject::acquire(); } - void SAL_CALL release() throw() { OWeakObject::release(); } + Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType); + void SAL_CALL acquire() { OWeakObject::acquire(); } + void SAL_CALL release() { OWeakObject::release(); } public: virtual void SAL_CALL setIn( const ::com::sun::star::uno::Reference< ::test::XCallMe >& callback ) throw(::com::sun::star::uno::RuntimeException); @@ -114,9 +114,9 @@ public: public: // XInterface - Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType) throw ( ::com::sun::star::uno::RuntimeException ); - void SAL_CALL acquire()throw() { OWeakObject::acquire(); } - void SAL_CALL release()throw() { OWeakObject::release(); } + Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType); + void SAL_CALL acquire() { OWeakObject::acquire(); } + void SAL_CALL release() { OWeakObject::release(); } public: // XCallMe virtual void SAL_CALL call( const ::rtl::OUString& s, sal_Int32 nToDo ) @@ -150,9 +150,9 @@ public: public: // XInterface - Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType ) throw ( ::com::sun::star::uno::RuntimeException ); - void SAL_CALL acquire()throw() { OWeakObject::acquire(); } - void SAL_CALL release() throw() { OWeakObject::release(); } + Any SAL_CALL queryInterface( const com::sun::star::uno::Type & aType ); + void SAL_CALL acquire() { OWeakObject::acquire(); } + void SAL_CALL release() { OWeakObject::release(); } public: virtual ::com::sun::star::uno::Reference< ::test::XCallMe > SAL_CALL createCallMe( ) throw(::com::sun::star::uno::RuntimeException); @@ -161,6 +161,28 @@ public: }; +/* +class OConnectCallback : + public ::cppu::OWeakObject, + public XConnectCallback +{ +public: + OConnectCallback( ){} + ~OConnectCallback(){ printf( "callback dies\n" );} +public: + // XInterface + Any SAL_CALL queryInterface( const Type & aType); + void SAL_CALL acquire() { OWeakObject::acquire(); } + void SAL_CALL release() { OWeakObject::release(); } + +public: + // XConnectCallback + virtual void SAL_CALL attemptConnect( + const Reference< XConnectionServerSide >& connection ) + throw(SecurityException, RuntimeException); +}; + +*/ class OInstanceProvider : public ::cppu::OWeakObject, @@ -174,11 +196,12 @@ public: ~OInstanceProvider(){ printf( "instance provider dies\n" );} public: // XInterface - Any SAL_CALL queryInterface( const Type & aType)throw ( ::com::sun::star::uno::RuntimeException ); - void SAL_CALL acquire()throw() { OWeakObject::acquire(); } - void SAL_CALL release() throw() { OWeakObject::release(); } + Any SAL_CALL queryInterface( const Type & aType); + void SAL_CALL acquire() { OWeakObject::acquire(); } + void SAL_CALL release() { OWeakObject::release(); } public: + // XConnectCallback virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getInstance( const ::rtl::OUString& sObjectName ) throw( ::com::sun::star::container::NoSuchElementException, diff --git a/bridges/test/testoffice.cxx b/bridges/test/testoffice.cxx index 1316f7320d66..7c63c642af73 100644 --- a/bridges/test/testoffice.cxx +++ b/bridges/test/testoffice.cxx @@ -2,9 +2,9 @@ * * $RCSfile: testoffice.cxx,v $ * - * $Revision: 1.4 $ + * $Revision: 1.5 $ * - * last change: $Author: jl $ $Date: 2001-03-14 09:25:39 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:10 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -170,7 +170,9 @@ void testWriter( const Reference < XComponent > & rCmp ) break; } - strcat( pcText , " " ); + if ( strlen( pcText ) < sizeof(pcText)-1 ) + strcat( pcText , " " ); // #100211# - checked + rText->insertString( rRange , OUString::createFromAscii( pcText ) , sal_False ); } } @@ -240,12 +242,12 @@ void doSomething( const Reference < XInterface > &r ) } -void main( int argc, char *argv[] ) +int main( int argc, char *argv[] ) { if( argc < 2 ) { printf( "usage : testclient host:port" ); - exit( 1 ); + return 0; } OUString sConnectionString; @@ -308,4 +310,5 @@ void main( int argc, char *argv[] ) rComp->dispose(); } //_getch(); + return 0; } diff --git a/bridges/test/testsameprocess.cxx b/bridges/test/testsameprocess.cxx index f4d8db6882d5..9778297e2367 100644 --- a/bridges/test/testsameprocess.cxx +++ b/bridges/test/testsameprocess.cxx @@ -2,9 +2,9 @@ * * $RCSfile: testsameprocess.cxx,v $ * - * $Revision: 1.6 $ + * $Revision: 1.7 $ * - * last change: $Author: jbu $ $Date: 2002-04-18 10:09:22 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:10 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -159,7 +159,7 @@ int main( int argc, char *argv[] ) if( argc < 2 ) { printf( "usage : testsamprocess host:port\n" ); - return 1; + return 0; } { diff --git a/bridges/test/testserver.cxx b/bridges/test/testserver.cxx index 8ba70e2f0f2e..3c2c8853305a 100644 --- a/bridges/test/testserver.cxx +++ b/bridges/test/testserver.cxx @@ -2,9 +2,9 @@ * * $RCSfile: testserver.cxx,v $ * - * $Revision: 1.7 $ + * $Revision: 1.8 $ * - * last change: $Author: jbu $ $Date: 2002-04-18 10:09:22 $ + * last change: $Author: hr $ $Date: 2003-03-18 19:07:10 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses @@ -223,7 +223,7 @@ int main( int argc, char *argv[] ) { printf( "usage : testserver [-r] connectionstring\n" " -r does a reverse test (server calls client)\n" ); - return 1; + return 0; } OUString sConnectionString; |