diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 14:29:57 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2000-09-18 14:29:57 +0000 |
commit | b525a3115f54576017a576ff842dede5e2e3545d (patch) | |
tree | c534b95a9e572b63896467624293a5ca1887d3a3 /bridges | |
parent | 9399c662f36c385b0c705eb34e636a9aec450282 (diff) |
initial import
Diffstat (limited to 'bridges')
75 files changed, 18388 insertions, 0 deletions
diff --git a/bridges/inc/bridges/cpp_uno/bridge.hxx b/bridges/inc/bridges/cpp_uno/bridge.hxx new file mode 100644 index 000000000000..ba25d64a7657 --- /dev/null +++ b/bridges/inc/bridges/cpp_uno/bridge.hxx @@ -0,0 +1,528 @@ +/************************************************************************* + * + * $RCSfile: bridge.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:47 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#define _BRIDGES_CPP_UNO_BRIDGE_HXX_ + +#ifndef _BRIDGES_CPP_UNO_BRIDGE_H_ +#include <bridges/cpp_uno/bridge.h> +#endif + +#ifndef _OSL_PROCESS_H_ +#include <osl/process.h> +#endif +#ifndef _RTL_PROCESS_H_ +#include <rtl/process.h> +#endif +#ifndef _RTL_USTRBUF_HXX_ +#include <rtl/ustrbuf.hxx> +#endif +#ifndef _COM_SUN_STAR_UNO_GENFUNC_HXX_ +#include <com/sun/star/uno/genfunc.hxx> +#endif + +#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HPP_ +#include <com/sun/star/uno/XInterface.hpp> +#endif + + +namespace CPPU_CURRENT_NAMESPACE +{ + +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_cppInterfaceProxy_free( uno_ExtEnvironment * pEnv, void * pProxy ) +{ + cppu_cppInterfaceProxy * pThis = + static_cast< cppu_cppInterfaceProxy * >( + reinterpret_cast< ::com::sun::star::uno::XInterface * >( pProxy ) ); + OSL_ASSERT( pEnv == pThis->pBridge->pCppEnv ); + + (*pThis->pBridge->pUnoEnv->revokeInterface)( pThis->pBridge->pUnoEnv, pThis->pUnoI ); + (*pThis->pUnoI->release)( pThis->pUnoI ); + ::typelib_typedescription_release( (typelib_TypeDescription *)pThis->pTypeDescr ); + pThis->pBridge->release(); + +#ifdef DEBUG + *(int *)pProxy = 0xdeadbabe; +#endif + delete pThis; +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_Mapping_uno2cpp( + uno_Mapping * pMapping, void ** ppCppI, + void * pUnoI, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + OSL_ASSERT( ppCppI && pTypeDescr ); + if (*ppCppI) + { + reinterpret_cast< ::com::sun::star::uno::XInterface * >( *ppCppI )->release(); + *ppCppI = 0; + } + if (pUnoI) + { + cppu_Bridge * pBridge = static_cast< cppu_Mapping * >( pMapping )->pBridge; + + // get object id of uno interface to be wrapped + rtl_uString * pOId = 0; + (*pBridge->pUnoEnv->getObjectIdentifier)( pBridge->pUnoEnv, &pOId, pUnoI ); + OSL_ASSERT( pOId ); + + // try to get any known interface from target environment + (*pBridge->pCppEnv->getRegisteredInterface)( + pBridge->pCppEnv, ppCppI, pOId, pTypeDescr ); + + if (! *ppCppI) // no existing interface, register new proxy interface + { + // try to publish a new proxy (ref count initially 1) + cppu_cppInterfaceProxy * pProxy = new cppu_cppInterfaceProxy( + pBridge, reinterpret_cast< uno_Interface * >( pUnoI ), pTypeDescr, pOId ); + ::com::sun::star::uno::XInterface * pSurrogate = pProxy; + cppu_cppInterfaceProxy_patchVtable( pSurrogate, pProxy->pTypeDescr ); + + // proxy may be exchanged during registration + (*pBridge->pCppEnv->registerProxyInterface)( + pBridge->pCppEnv, reinterpret_cast< void ** >( &pSurrogate ), + cppu_cppInterfaceProxy_free, pOId, pTypeDescr ); + + *ppCppI = pSurrogate; + } + ::rtl_uString_release( pOId ); + } +} +//__________________________________________________________________________________________________ +inline void cppu_cppInterfaceProxy::acquireProxy() +{ + if (1 == osl_incrementInterlockedCount( &nRef )) + { + // rebirth of proxy zombie + // register at cpp env + void * pThis = static_cast< ::com::sun::star::uno::XInterface * >( this ); + (*pBridge->pCppEnv->registerProxyInterface)( + pBridge->pCppEnv, &pThis, cppu_cppInterfaceProxy_free, oid.pData, pTypeDescr ); + OSL_ASSERT( pThis == static_cast< ::com::sun::star::uno::XInterface * >( this ) ); + } +} +//__________________________________________________________________________________________________ +inline void cppu_cppInterfaceProxy::releaseProxy() +{ + if (! osl_decrementInterlockedCount( &nRef )) // last release + { + // revoke from cpp env + (*pBridge->pCppEnv->revokeInterface)( + pBridge->pCppEnv, static_cast< ::com::sun::star::uno::XInterface * >( this ) ); + } +} +//__________________________________________________________________________________________________ +inline cppu_cppInterfaceProxy::cppu_cppInterfaceProxy( + cppu_Bridge * pBridge_, uno_Interface * pUnoI_, + typelib_InterfaceTypeDescription * pTypeDescr_, const ::rtl::OUString & rOId_ ) + : nRef( 1 ) + , pBridge( pBridge_ ) + , pUnoI( pUnoI_ ) + , pTypeDescr( pTypeDescr_ ) + , oid( rOId_ ) +{ + pBridge->acquire(); + ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr ); + if (! ((typelib_TypeDescription *)pTypeDescr)->bComplete) + ::typelib_typedescription_complete( (typelib_TypeDescription **)&pTypeDescr ); + (*pBridge->pUnoEnv->registerInterface)( + pBridge->pUnoEnv, reinterpret_cast< void ** >( &pUnoI ), oid.pData, pTypeDescr ); + (*pUnoI->acquire)( pUnoI ); +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_unoInterfaceProxy_free( uno_ExtEnvironment * pEnv, void * pProxy ) +{ + cppu_unoInterfaceProxy * pThis = + static_cast< cppu_unoInterfaceProxy * >( + reinterpret_cast< uno_Interface * >( pProxy ) ); + OSL_ASSERT( pEnv == pThis->pBridge->pUnoEnv ); + + (*pThis->pBridge->pCppEnv->revokeInterface)( pThis->pBridge->pCppEnv, pThis->pCppI ); + pThis->pCppI->release(); + ::typelib_typedescription_release( (typelib_TypeDescription *)pThis->pTypeDescr ); + pThis->pBridge->release(); + +#ifdef DEBUG + *(int *)pProxy = 0xdeadbabe; +#endif + delete pThis; +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_unoInterfaceProxy_acquire( uno_Interface * pUnoI ) +{ + if (1 == osl_incrementInterlockedCount( & static_cast< cppu_unoInterfaceProxy * >( pUnoI )->nRef )) + { + // rebirth of proxy zombie + // register at uno env +#ifdef DEBUG + void * pThis = pUnoI; +#endif + (*static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv->registerProxyInterface)( + static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv, + reinterpret_cast< void ** >( &pUnoI ), cppu_unoInterfaceProxy_free, + static_cast< cppu_unoInterfaceProxy * >( pUnoI )->oid.pData, + static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pTypeDescr ); +#ifdef DEBUG + OSL_ASSERT( pThis == pUnoI ); +#endif + } +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_unoInterfaceProxy_release( uno_Interface * pUnoI ) +{ + if (! osl_decrementInterlockedCount( & static_cast< cppu_unoInterfaceProxy * >( pUnoI )->nRef )) + { + // revoke from uno env on last release + (*static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv->revokeInterface)( + static_cast< cppu_unoInterfaceProxy * >( pUnoI )->pBridge->pUnoEnv, pUnoI ); + } +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_Mapping_cpp2uno( + uno_Mapping * pMapping, void ** ppUnoI, + void * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + OSL_ENSHURE( ppUnoI && pTypeDescr, "### null ptr!" ); + if (*ppUnoI) + { + (*reinterpret_cast< uno_Interface * >( *ppUnoI )->release)( + reinterpret_cast< uno_Interface * >( *ppUnoI ) ); + *ppUnoI = 0; + } + if (pCppI) + { + cppu_Bridge * pBridge = static_cast< cppu_Mapping * >( pMapping )->pBridge; + + // get object id of interface to be wrapped + rtl_uString * pOId = 0; + (*pBridge->pCppEnv->getObjectIdentifier)( pBridge->pCppEnv, &pOId, pCppI ); + OSL_ASSERT( pOId ); + + // try to get any known interface from target environment + (*pBridge->pUnoEnv->getRegisteredInterface)( + pBridge->pUnoEnv, ppUnoI, pOId, pTypeDescr ); + + if (! *ppUnoI) // no existing interface, register new proxy interface + { + // try to publish a new proxy (refcount initially 1) + uno_Interface * pSurrogate = new cppu_unoInterfaceProxy( + pBridge, reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI ), + pTypeDescr, pOId ); + + // proxy may be exchanged during registration + (*pBridge->pUnoEnv->registerProxyInterface)( + pBridge->pUnoEnv, reinterpret_cast< void ** >( &pSurrogate ), + cppu_unoInterfaceProxy_free, pOId, pTypeDescr ); + + *ppUnoI = pSurrogate; + } + ::rtl_uString_release( pOId ); + } +} +//__________________________________________________________________________________________________ +inline cppu_unoInterfaceProxy::cppu_unoInterfaceProxy( + cppu_Bridge * pBridge_, ::com::sun::star::uno::XInterface * pCppI_, + typelib_InterfaceTypeDescription * pTypeDescr_, const ::rtl::OUString & rOId_ ) + : nRef( 1 ) + , pBridge( pBridge_ ) + , pCppI( pCppI_ ) + , pTypeDescr( pTypeDescr_ ) + , oid( rOId_ ) +{ + pBridge->acquire(); + ::typelib_typedescription_acquire( (typelib_TypeDescription *)pTypeDescr ); + if (! ((typelib_TypeDescription *)pTypeDescr)->bComplete) + ::typelib_typedescription_complete( (typelib_TypeDescription **)&pTypeDescr ); + (*pBridge->pCppEnv->registerInterface)( + pBridge->pCppEnv, reinterpret_cast< void ** >( &pCppI ), oid.pData, pTypeDescr ); + pCppI->acquire(); + + // uno_Interface + uno_Interface::acquire = CPPU_CURRENT_NAMESPACE::cppu_unoInterfaceProxy_acquire; + uno_Interface::release = CPPU_CURRENT_NAMESPACE::cppu_unoInterfaceProxy_release; + uno_Interface::pDispatcher = CPPU_CURRENT_NAMESPACE::cppu_unoInterfaceProxy_dispatch; +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + + +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_Mapping_acquire( uno_Mapping * pMapping ) +{ + static_cast< cppu_Mapping * >( pMapping )->pBridge->acquire(); +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_Mapping_release( uno_Mapping * pMapping ) +{ + static_cast< cppu_Mapping * >( pMapping )->pBridge->release(); +} +//__________________________________________________________________________________________________ +inline cppu_Mapping::cppu_Mapping( cppu_Bridge * pBridge_, uno_MapInterfaceFunc fpMap ) + : pBridge( pBridge_ ) +{ + uno_Mapping::acquire = cppu_Mapping_acquire; + uno_Mapping::release = cppu_Mapping_release; + uno_Mapping::mapInterface = fpMap; +} +//__________________________________________________________________________________________________ +inline cppu_Bridge::cppu_Bridge( uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_, + sal_Bool bExportCpp2Uno_ ) + : nRef( 1 ) + , pCppEnv( pCppEnv_ ) + , pUnoEnv( pUnoEnv_ ) + , aCpp2Uno( this, cppu_Mapping_cpp2uno ) + , aUno2Cpp( this, cppu_Mapping_uno2cpp ) + , bExportCpp2Uno( bExportCpp2Uno_ ) +{ + (*((uno_Environment *)pCppEnv)->acquire)( (uno_Environment *)pCppEnv ); + (*((uno_Environment *)pUnoEnv)->acquire)( (uno_Environment *)pUnoEnv ); +} +//__________________________________________________________________________________________________ +inline void SAL_CALL cppu_Bridge_free( uno_Mapping * pMapping ) +{ + cppu_Bridge * pThis = static_cast< cppu_Mapping * >( pMapping )->pBridge; + (*((uno_Environment *)pThis->pUnoEnv)->release)( (uno_Environment *)pThis->pUnoEnv ); + (*((uno_Environment *)pThis->pCppEnv)->release)( (uno_Environment *)pThis->pCppEnv ); + delete pThis; +} +//__________________________________________________________________________________________________ +inline void cppu_Bridge::acquire() +{ + if (1 == osl_incrementInterlockedCount( &nRef )) + { + if (bExportCpp2Uno) + { + uno_Mapping * pMapping = &aCpp2Uno; + uno_registerMapping( &pMapping, cppu_Bridge_free, + (uno_Environment *)pCppEnv, (uno_Environment *)pUnoEnv, 0 ); + } + else + { + uno_Mapping * pMapping = &aUno2Cpp; + uno_registerMapping( &pMapping, cppu_Bridge_free, + (uno_Environment *)pUnoEnv, (uno_Environment *)pCppEnv, 0 ); + } + } +} +//__________________________________________________________________________________________________ +inline void cppu_Bridge::release() +{ + if (! osl_decrementInterlockedCount( &nRef )) + { + uno_revokeMapping( bExportCpp2Uno ? &aCpp2Uno : &aUno2Cpp ); + } +} + +//################################################################################################## +inline void SAL_CALL cppu_ext_getMapping( + uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) +{ + OSL_ASSERT( ppMapping && pFrom && pTo ); + if (ppMapping && pFrom && pTo && pFrom->pExtEnv && pTo->pExtEnv) + { + uno_Mapping * pMapping = 0; + + if (0 == rtl_ustr_ascii_compare( pFrom->pTypeName->buffer, CPPU_CURRENT_LANGUAGE_BINDING_NAME ) && + 0 == rtl_ustr_ascii_compare( pTo->pTypeName->buffer, UNO_LB_UNO )) + { + // ref count initially 1 + pMapping = &(new cppu_Bridge( pFrom->pExtEnv, pTo->pExtEnv, sal_True ))->aCpp2Uno; + ::uno_registerMapping( &pMapping, cppu_Bridge_free, + (uno_Environment *)pFrom->pExtEnv, + (uno_Environment *)pTo->pExtEnv, 0 ); + } + if (0 == rtl_ustr_ascii_compare( pTo->pTypeName->buffer, CPPU_CURRENT_LANGUAGE_BINDING_NAME ) && + 0 == rtl_ustr_ascii_compare( pFrom->pTypeName->buffer, UNO_LB_UNO )) + { + // ref count initially 1 + pMapping = &(new cppu_Bridge( pTo->pExtEnv, pFrom->pExtEnv, sal_False ))->aUno2Cpp; + ::uno_registerMapping( &pMapping, cppu_Bridge_free, + (uno_Environment *)pFrom->pExtEnv, + (uno_Environment *)pTo->pExtEnv, 0 ); + } + + if (*ppMapping) + (*(*ppMapping)->release)( *ppMapping ); + *ppMapping = pMapping; + } +} + + +//################################################################################################## +//################################################################################################## +//################################################################################################## + +#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__)) +static ::rtl::OUString * s_pStaticOidPart = 0; +#endif + +// environment init stuff +//-------------------------------------------------------------------------------------------------- +inline const ::rtl::OUString & SAL_CALL cppu_cppenv_getStaticOIdPart() +{ +#if ! ((defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__))) + static ::rtl::OUString * s_pStaticOidPart = 0; +#endif + if (! s_pStaticOidPart) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if (! s_pStaticOidPart) + { + ::rtl::OUStringBuffer aRet( 64 ); + aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") ); + // pid + oslProcessInfo info; + info.Size = sizeof(oslProcessInfo); + if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) == osl_Process_E_None) + { + aRet.append( (sal_Int64)info.Ident, 16 ); + } + else + { + aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("unknown process id") ); + } + // good guid + sal_uInt8 ar[16]; + ::rtl_getGlobalProcessId( ar ); + aRet.append( (sal_Unicode)';' ); + for ( sal_Int32 i = 0; i < 16; ++i ) + { + aRet.append( (sal_Int32)ar[i], 16 ); + } +#if (defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500)) || (defined(__GNUC__) && defined(__APPLE__)) + s_pStaticOidPart = new ::rtl::OUString( aRet.makeStringAndClear() ); +#else + static ::rtl::OUString s_aStaticOidPart( aRet.makeStringAndClear() ); + s_pStaticOidPart = &s_aStaticOidPart; +#endif + } + } + return *s_pStaticOidPart; +} +// functions set at environment init +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_cppenv_computeObjectIdentifier( + uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) +{ + OSL_ENSHURE( pEnv && ppOId && pInterface, "### null ptr!" ); + if (pEnv && ppOId && pInterface) + { + if (*ppOId) + { + rtl_uString_release( *ppOId ); + *ppOId = 0; + } + + ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xHome( + reinterpret_cast< ::com::sun::star::uno::XInterface * >( pInterface ), + ::com::sun::star::uno::UNO_QUERY ); + OSL_ENSHURE( xHome.is(), "### query to XInterface failed!" ); + if (xHome.is()) + { + // interface + ::rtl::OUStringBuffer oid( 64 ); + oid.append( (sal_Int64)xHome.get(), 16 ); + oid.append( (sal_Unicode)';' ); + // environment[context] + oid.append( ((uno_Environment *)pEnv)->pTypeName ); + oid.append( (sal_Unicode)'[' ); + oid.append( (sal_Int64)((uno_Environment *)pEnv)->pContext, 16 ); + // process;good guid + oid.append( cppu_cppenv_getStaticOIdPart() ); + ::rtl::OUString aRet( oid.makeStringAndClear() ); + ::rtl_uString_acquire( *ppOId = aRet.pData ); + } + } +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_cppenv_acquireInterface( uno_ExtEnvironment *, void * pCppI ) +{ + reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->acquire(); +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_cppenv_releaseInterface( uno_ExtEnvironment *, void * pCppI ) +{ + reinterpret_cast< ::com::sun::star::uno::XInterface * >( pCppI )->release(); +} +//-------------------------------------------------------------------------------------------------- +inline void SAL_CALL cppu_cppenv_initEnvironment( uno_Environment * pCppEnv ) +{ + OSL_ENSHURE( pCppEnv->pExtEnv, "### expected extended environment!" ); + OSL_ENSHURE( rtl_ustr_ascii_compare( pCppEnv->pTypeName->buffer, CPPU_CURRENT_LANGUAGE_BINDING_NAME ) == 0, + "### wrong environment type!" ); + ((uno_ExtEnvironment *)pCppEnv)->computeObjectIdentifier = CPPU_CURRENT_NAMESPACE::cppu_cppenv_computeObjectIdentifier; + ((uno_ExtEnvironment *)pCppEnv)->acquireInterface = CPPU_CURRENT_NAMESPACE::cppu_cppenv_acquireInterface; + ((uno_ExtEnvironment *)pCppEnv)->releaseInterface = CPPU_CURRENT_NAMESPACE::cppu_cppenv_releaseInterface; +} + +} + +#endif diff --git a/bridges/inc/bridges/cpp_uno/type_misc.hxx b/bridges/inc/bridges/cpp_uno/type_misc.hxx new file mode 100644 index 000000000000..ec863e4887de --- /dev/null +++ b/bridges/inc/bridges/cpp_uno/type_misc.hxx @@ -0,0 +1,155 @@ +/************************************************************************* + * + * $RCSfile: type_misc.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:47 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ +#define _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ + +#ifndef _SAL_TYPES_H_ +#include <sal/types.h> +#endif +#ifndef _TYPELIB_TYPEDESCRIPTION_H_ +#include <typelib/typedescription.h> +#endif + + +/** Determines whether given type might relate or relates to an interface, + i.e. values of this type are interface or may contain interface(s).<br> + @param pTypeDescr type description of type + @return true if type might relate to an interface, false otherwise +*/ +inline sal_Bool SAL_CALL cppu_relatesToInterface( typelib_TypeDescription * pTypeDescr ) +{ + switch (pTypeDescr->eTypeClass) + { +// case typelib_TypeClass_TYPEDEF: + case typelib_TypeClass_SEQUENCE: + { + switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return sal_True; + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType ); + sal_Bool bRel = cppu_relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + return bRel; + } + } + return sal_False; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + // ...optimized... to avoid getDescription() calls! + typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr; + typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs; + for ( sal_Int32 nPos = pComp->nMembers; nPos--; ) + { + switch (pTypes[nPos]->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return sal_True; +// case typelib_TypeClass_TYPEDEF: + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pTypes[nPos] ); + sal_Bool bRel = cppu_relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + if (bRel) + return sal_True; + } + } + } + if (pComp->pBaseTypeDescription) + return cppu_relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription ); + break; + } + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + case typelib_TypeClass_INTERFACE: + return sal_True; + } + return sal_False; +} + +/** Determines whether given type is a cpp simple type, e.g. int, enum.<br> + @param pTypeDescr type description of type + @return true if type is a cpp simple type, false otherwise +*/ +inline sal_Bool SAL_CALL cppu_isSimpleType( typelib_TypeDescription * pTypeDescr ) +{ + return (pTypeDescr->eTypeClass <= typelib_TypeClass_ENUM && + pTypeDescr->eTypeClass != typelib_TypeClass_STRING && + pTypeDescr->eTypeClass != typelib_TypeClass_ANY && + pTypeDescr->eTypeClass != typelib_TypeClass_TYPE); +} + +#endif diff --git a/bridges/inc/bridges/remote/bridgeimpl.hxx b/bridges/inc/bridges/remote/bridgeimpl.hxx new file mode 100644 index 000000000000..15151185c74b --- /dev/null +++ b/bridges/inc/bridges/remote/bridgeimpl.hxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * $RCSfile: bridgeimpl.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:47 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_BRIDGEIMPL_HXX_ +#define _BRIDGES_REMOTE_BRIDGEIMPL_HXX_ + +#include <osl/interlck.h> + +#include <uno/environment.h> + +#include <bridges/remote/context.h> +#include <bridges/remote/remote.h> + + +struct remote_BridgeImpl +{ + void (SAL_CALL * m_allThreadsAreGone ) ( uno_Environment * ); + requestClientSideDispatcher m_sendRequest; + oslInterlockedCount m_nRemoteThreads; + sal_Bool m_bDisposed; + sal_Bool m_bReleaseStubsCalled; +}; + +namespace bridges_remote { + + enum RemoteThreadCounter_HoldEnvWeak + { + RTC_HOLDENVWEAK = 0x1 + }; + + class RemoteThreadCounter + { + public: + // performance optimization. In some cases, it is not necessary to acquire the + // environment. + RemoteThreadCounter( uno_Environment *pEnvRemote, RemoteThreadCounter_HoldEnvWeak value ) + : m_pEnvRemote( pEnvRemote ) + , m_bReleaseEnvironment( sal_False ) + { + remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext ); + osl_incrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads ) ); + } + + RemoteThreadCounter( uno_Environment *pEnvRemote ) + : m_pEnvRemote( pEnvRemote ) + , m_bReleaseEnvironment( sal_True ) + { + m_pEnvRemote->acquire( m_pEnvRemote ); + + remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext ); + osl_incrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads ) ); + } + + ~RemoteThreadCounter( ) + { + remote_Context *pContext = ((remote_Context *) m_pEnvRemote->pContext ); + if( 0 == osl_decrementInterlockedCount( &( pContext->m_pBridgeImpl->m_nRemoteThreads)) && + pContext->m_pBridgeImpl->m_bDisposed && + ! pContext->m_pBridgeImpl->m_bReleaseStubsCalled ) + { + pContext->m_pBridgeImpl->m_allThreadsAreGone( m_pEnvRemote ); + } + if( m_bReleaseEnvironment ) + m_pEnvRemote->release( m_pEnvRemote ); + } + + sal_Bool m_bReleaseEnvironment; + uno_Environment *m_pEnvRemote; + }; +} + +#endif diff --git a/bridges/inc/bridges/remote/connection.h b/bridges/inc/bridges/remote/connection.h new file mode 100644 index 000000000000..32806c58e909 --- /dev/null +++ b/bridges/inc/bridges/remote/connection.h @@ -0,0 +1,99 @@ +/************************************************************************* + * + * $RCSfile: connection.h,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:47 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_CONNECTION_H_ +#define _BRIDGES_REMOTE_CONNECTION_H_ +#include <sal/types.h> + +struct remote_Connection +{ + void ( SAL_CALL * acquire ) ( remote_Connection *); + + void ( SAL_CALL * release ) ( remote_Connection *); + + + /*** + * reads nSize bytes from the connection. This method blocks, until + * all bytes are available or an error occurs. + * @return Number of bytes read.<br> + * If the return value is less than nSize, an unrecoverable + * i/o error has occured or the connection was closed. + * + ***/ + sal_Int32 (SAL_CALL * read)(remote_Connection *, sal_Int8 *pDest, sal_Int32 nSize ); + + /*** + * @return Number of bytes written.<br> + * if the return value is less than nSize an unrecoverable + * i/o error has occured or the connection was closed. + ***/ + sal_Int32 (SAL_CALL * write)(remote_Connection *, const sal_Int8 *pSource, sal_Int32 nSize ); + + void ( SAL_CALL * flush ) ( remote_Connection * ); + + /*** + * closes the connection. Any read or write operation after this call shall not be served + * anymore. Any ongoing read or write operation must return immeadiatly after this call. + * The implementation should cope with multiple calls to this method. + ***/ + void (SAL_CALL * close) ( remote_Connection * ); +}; + +#endif diff --git a/bridges/inc/bridges/remote/context.h b/bridges/inc/bridges/remote/context.h new file mode 100644 index 000000000000..31b2213f318f --- /dev/null +++ b/bridges/inc/bridges/remote/context.h @@ -0,0 +1,263 @@ +/************************************************************************* + * + * $RCSfile: context.h,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _BRIDGES_REMOTE_CONTEXT_H_ +#define _BRIDGES_REMOTE_CONTEXT_H_ +#include <osl/interlck.h> +#include <osl/conditn.h> + +#include <typelib/typedescription.h> + +#include <uno/environment.h> + +struct uno_Context +{ + void (SAL_CALL * acquire)( uno_Context *pContext ); + + void (SAL_CALL * release)( uno_Context *pContext); + + void * (SAL_CALL *query ) ( uno_Context *pContext , rtl_uString *pId); +}; + +struct remote_Connection; +struct remote_Context; +struct remote_Interface; + + +/***** + * @deprecated + ****/ +typedef void ( SAL_CALL * remote_createStubFunc ) ( + remote_Interface **ppRemoteI, + rtl_uString *pOid , + typelib_TypeDescriptionReference *pTypeRef, + uno_Environment *pEnvRemote ); + +/*** + * performs a query-interface for a certain interface via the remote connection ! + * + * @param pEnvRemote The environment, that shall perform the call. + * @param ppRemoteI in/out parameter contains the interface returned by queryInterface + * @param pOid the oid of the 'ghost' object on which the call must be done. + ***/ +typedef void ( SAL_CALL * remote_getInstanceFunc ) ( + uno_Environment *pEnvRemote, + remote_Interface **ppRemoteI, + rtl_uString *pOid, + typelib_TypeDescriptionReference *pInterfaceTypeRef); + +struct remote_InstanceProvider +{ + void (SAL_CALL * acquire ) ( remote_InstanceProvider * pProvider ); + void (SAL_CALL * release ) ( remote_InstanceProvider * pProvider ); + void (SAL_CALL * getInstance ) ( remote_InstanceProvider * pProvider , + uno_Environment *pEnvRemote, + remote_Interface **ppRemoteI, + rtl_uString *pInstanceName, + typelib_InterfaceTypeDescription *pType + ); +}; + +struct remote_DisposingListener +{ + void (SAL_CALL * acquire ) ( remote_DisposingListener * pProvider ); + void (SAL_CALL * release ) ( remote_DisposingListener * pProvider ); + void (SAL_CALL * disposing ) ( remote_DisposingListener * pProvider, + rtl_uString *pBridgeName ); +}; + + +/** + * Try to get an existing context characterized by the IDString. Each ID-String must + * uniquely charcterize a certain connection. + * + * @return 0 when such a context does not exist, otherwise + * a pointer to an acquired uno remote context + **/ +extern "C" SAL_DLLEXPORT remote_Context * SAL_CALL +remote_getContext( rtl_uString *pIdString ); + +/** + * Create an acquired remote context. The Context is weakly held by the context administration + * and can be accessed later through getRemoteContext() (using the same id-string). + * + * @param pIdString A string, that uniquely describes the connection. For e.g. a socket connection, + * host and port of the local and remote host should be in the string. + * + * @param pDescription + * Description of the connection, that may brought up to the user. + * + * @param pProtocol + * The protocol, that the environment uses for + * communicating with the remote process. + * The format of the protocol string is : "protocolname,para1=para1value,..." + * @return 0, when a context with this name already exists. + **/ +extern "C" SAL_DLLEXPORT remote_Context * SAL_CALL +remote_createContext( remote_Connection *pConnection, + rtl_uString *pIdStr, + rtl_uString *pDescription, + rtl_uString *pProtocol, + remote_InstanceProvider *); + +const sal_Int32 REMOTE_CONTEXT_CREATE = 1; +const sal_Int32 REMOTE_CONTEXT_DESTROY = 2; + +typedef void ( SAL_CALL * remote_contextListenerFunc ) ( + void *pThis, + sal_Int32 nRemoteContextMode, + rtl_uString *sName, + rtl_uString *sDescription + ); + + +extern "C" SAL_DLLEXPORT void SAL_CALL +remote_addContextListener( remote_contextListenerFunc listener, void *pObject ); + +extern "C" SAL_DLLEXPORT void SAL_CALL +remote_removeContextListener( remote_contextListenerFunc listener , void *pObject ); + +/**** + * @param pnStringCount out parameter. Contains the number of rtl_uStrings in the array + * @param memAlloc a memory allocation function for the array of pointers to rtl_uStrings + * + * @return array of rtl strings. The caller must call release on all rtl_uString s and must free + * the pointer array. + * + ***/ +extern "C" SAL_DLLEXPORT rtl_uString ** SAL_CALL +remote_getContextList( + sal_Int32 *pnStringCount, + void * ( SAL_CALL * memAlloc ) ( sal_uInt32 nBytesToAlloc ) ); + + +struct remote_BridgeImpl; + +struct remote_Context +{ + struct uno_Context aBase; + + /*** + * These methods are implemented by context administration + ***/ + void ( SAL_CALL * addDisposingListener ) ( remote_Context *, + remote_DisposingListener * ); + void ( SAL_CALL * removeDisposingListener ) ( remote_Context *, + remote_DisposingListener * ); + /*** + * will be called by the environment when it gets disposed + ***/ + void ( SAL_CALL * dispose ) ( remote_Context * ); + + /******** + * see above declaration of remote_getInstanceFunc + * The method is set by the environment during environment initialization. + *******/ + remote_getInstanceFunc getRemoteInstance; + + /******* + * The protocol, that the environment uses for communicating with the remote process. + * The format of the protocol string is : "protocolname,para1=para1value,..." + * The parameters are protocol dependend + ******/ + rtl_uString *m_pProtocol; + + /**** + * It may be the same as m_pName. + * Livetime is handled by the context administration. + ****/ + rtl_uString *m_pDescription; + + /**** + * The name of this context at context administration. + * A string, that uniquely describes this environment. + * Livetime is handled by the context administration. + ****/ + rtl_uString *m_pName; + + /** + * GetInstance method is called every time when a remote call with an unknown oid comes in. + * Is usually called on server side, when the first client request comes in. + * Maybe 0. Livetime is handled by the context administration. + ***/ + remote_InstanceProvider *m_pInstanceProvider; + + /*** + * The connection of this context. + * Livetime is handled by the context administration. + ***/ + remote_Connection *m_pConnection; + + /** + * Here arbitrary data may be stored. It may be used by a connection + * service to store environment specific data. The bridge does not + * use it. + **/ + void *m_pAdditionalInformation; + + /** + * here the bridge stores its private per environment data. + **/ + struct remote_BridgeImpl *m_pBridgeImpl; +}; + +#endif + diff --git a/bridges/inc/bridges/remote/counter.hxx b/bridges/inc/bridges/remote/counter.hxx new file mode 100644 index 000000000000..085fd1eb98d5 --- /dev/null +++ b/bridges/inc/bridges/remote/counter.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * $RCSfile: counter.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_COUNTER_H_ +#define _BRIDGES_REMOTE_COUNTER_H_ +#include <stdio.h> + +#ifdef DEBUG +struct MyCounter +{ + MyCounter( sal_Char *pName ) : + m_pName ( pName ), + m_nCounter( 0 ) + { + } + ~MyCounter() + { + if( m_nCounter ) { + printf( "%s : %d left\n", m_pName , m_nCounter ); + } + } + void acquire() + { m_nCounter ++; } + void release() + { m_nCounter --; } + + + sal_Int32 m_nCounter; + sal_Char *m_pName; +}; +#endif + +#endif diff --git a/bridges/inc/bridges/remote/helper.hxx b/bridges/inc/bridges/remote/helper.hxx new file mode 100644 index 000000000000..c6eff3044dff --- /dev/null +++ b/bridges/inc/bridges/remote/helper.hxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * $RCSfile: helper.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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 <bridges/remote/bridgeimpl.hxx> + +namespace bridges_remote +{ + void SAL_CALL remote_createStub ( + remote_Interface **ppRemoteI, + rtl_uString *pOid , + typelib_TypeDescriptionReference *pType, + uno_Environment *pEnvRemote ); + + void SAL_CALL remote_retrieveOidFromProxy( + remote_Interface *pRemtoeI, + rtl_uString **ppOid ); + + void SAL_CALL remote_sendQueryInterface( + uno_Environment *pEnvRemote, + remote_Interface **ppRemoteI, + rtl_uString *pOid , + typelib_TypeDescriptionReference *pType + ); +} diff --git a/bridges/inc/bridges/remote/mapping.hxx b/bridges/inc/bridges/remote/mapping.hxx new file mode 100644 index 000000000000..4dd83c3c6c2f --- /dev/null +++ b/bridges/inc/bridges/remote/mapping.hxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * $RCSfile: mapping.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_MAPPING_HXX_ +#define _BRIDGES_REMOTE_MAPPING_HXX_ + +#include <osl/interlck.h> +#include <rtl/ustring.hxx> + +#include <typelib/typedescription.h> + +#include <bridges/remote/remote.h> + +typedef struct _uno_Environment uno_Environment; + +namespace bridges_remote +{ + class RemoteMapping : + public remote_Mapping + { + public: + RemoteMapping( uno_Environment *pEnvUno , + uno_Environment *pEnvRemote, + uno_MapInterfaceFunc func , + const ::rtl::OUString sPurpose); + ~RemoteMapping(); + + static void SAL_CALL thisFree( uno_Mapping * pMapping ); + static void SAL_CALL remoteToUno( + uno_Mapping *pMapping, + void **ppOut, + void *pInterface, + typelib_InterfaceTypeDescription *pInterfaceTypeDescr ); + + static void SAL_CALL unoToRemote( + uno_Mapping *pMapping, + void **ppOut, + void *pInterface, + typelib_InterfaceTypeDescription *pInterfaceTypeDescr ); + + static void SAL_CALL thisAcquire( uno_Mapping *pMapping ); + static void SAL_CALL thisRelease( uno_Mapping *pMapping ); + + oslInterlockedCount m_nRef; + ::rtl::OUString m_sPurpose; + }; + +} +#endif diff --git a/bridges/inc/bridges/remote/proxy.hxx b/bridges/inc/bridges/remote/proxy.hxx new file mode 100644 index 000000000000..b970c9bf02f8 --- /dev/null +++ b/bridges/inc/bridges/remote/proxy.hxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * $RCSfile: proxy.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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 <osl/interlck.h> + +#include <uno/environment.h> +#include <uno/dispatcher.h> +#include <uno/mapping.hxx> + +#include <bridges/remote/remote.h> + +namespace bridges_remote { + +void SAL_CALL remote_release( void * ); +class Remote2UnoProxy : + public uno_Interface +{ +public: + Remote2UnoProxy( + remote_Interface *pRemoteI, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType , + uno_Environment *pEnvUno, + uno_Environment *pEnvRemote + ); + + ~Remote2UnoProxy(); + + static void SAL_CALL thisAcquire( uno_Interface * ); + static void SAL_CALL thisRelease( uno_Interface * ); + static void SAL_CALL thisDispatch( uno_Interface * pUnoI, + typelib_TypeDescription * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ); + static void SAL_CALL thisFree( uno_ExtEnvironment *pEnvUno, void *pProxy ); + +private: + ::rtl::OUString m_sOid; + typelib_InterfaceTypeDescription *m_pType; + remote_Interface *m_pRemoteI; + uno_Environment *m_pEnvUno; + uno_Environment *m_pEnvRemote; + ::com::sun::star::uno::Mapping m_mapRemote2Uno; + ::com::sun::star::uno::Mapping m_mapUno2Remote; + + oslInterlockedCount m_nRef; +}; + +} diff --git a/bridges/inc/bridges/remote/remote.h b/bridges/inc/bridges/remote/remote.h new file mode 100644 index 000000000000..f0d42d43d177 --- /dev/null +++ b/bridges/inc/bridges/remote/remote.h @@ -0,0 +1,118 @@ +/************************************************************************* + * + * $RCSfile: remote.h,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_REMOTE_H +#define _BRIDGES_REMOTE_REMOTE_H +#include <uno/mapping.h> +#include <uno/any2.h> + +#include <typelib/typedescription.h> + +#define UNO_LB_REMOTE "remote" + +#define CORBA_STRING8_NAME "com.sun.star.corba.CorbaString8" +#define CORBA_STRING8_NAME_LENGTH (sizeof(CORBA_STRING8_NAME)-1) + +#define CORBA_UNION_NAME "com.sun.star.corba.CorbaUnion" +#define CORBA_UNION_NAME_LENGTH (sizeof(CORBA_UNION_NAME)-1) + +#define REMOTE_MARSHALED_MSGHDR_SIZE 12 +#define REMOTE_RELEASE_METHOD_INDEX 2 +#define REMOTE_RELEASE_METHOD_NAME "release" + +#define CURRENT_IIOP_PROTOCOL_MAJOR 1 +#define CURRENT_IIOP_PROTOCOL_MINOR 2 + +struct remote_Interface; + +typedef void (SAL_CALL * remote_DispatchMethod)( remote_Interface * pRemoteI, + typelib_TypeDescription * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ); + + +typedef void ( SAL_CALL * requestClientSideDispatcher ) ( + uno_Environment *pEnvRemote, + typelib_TypeDescription * pMemberType, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pInterfaceType, + void *pReturn, + void *ppArgs[], + uno_Any **ppException ); + +struct remote_Interface +{ + void (SAL_CALL * acquire)( remote_Interface * pInterface ); + + void (SAL_CALL * release)( remote_Interface * pInterface ); + + remote_DispatchMethod pDispatcher; +}; + + +struct remote_Mapping +{ + uno_Mapping aBase; + uno_Environment *pEnvRemote; + uno_Environment *pEnvUno; +}; + +#endif diff --git a/bridges/inc/bridges/remote/remote.hxx b/bridges/inc/bridges/remote/remote.hxx new file mode 100644 index 000000000000..0e4aa39cd32a --- /dev/null +++ b/bridges/inc/bridges/remote/remote.hxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * $RCSfile: remote.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_REMOTE_HXX_ +#define _BRIDGES_REMOTE_REMOTE_HXX_ +#include <list> + +#include <osl/mutex.hxx> +#include <osl/conditn.h> +#include <osl/interlck.h> + +#include <vos/thread.hxx> + +#include <uno/environment.h> + +#include <bridges/remote/remote.h> +#include <bridges/remote/connection.h> + +#include <com/sun/star/uno/Sequence.hxx> + +namespace bridges_remote { + +class Remote2RemoteStub : + public remote_Interface +{ +public: + Remote2RemoteStub(rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvRemote, + requestClientSideDispatcher dispatch ); + ~Remote2RemoteStub(); + + static void SAL_CALL thisAcquire( remote_Interface *pThis ); + static void SAL_CALL thisRelease( remote_Interface *pThis ); + static void SAL_CALL thisDispatch( remote_Interface * pUnoI, + typelib_TypeDescription * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ); + static void SAL_CALL thisFree( uno_ExtEnvironment *pEnvRemote , void * ); + + void releaseRemote(); +public: + ::rtl::OUString m_sOid; + typelib_InterfaceTypeDescription *m_pType; + oslInterlockedCount m_nRef; + uno_Environment *m_pEnvRemote; + requestClientSideDispatcher m_dispatch; +}; + +} +#endif diff --git a/bridges/inc/bridges/remote/stub.hxx b/bridges/inc/bridges/remote/stub.hxx new file mode 100644 index 000000000000..dd068b3e3aa8 --- /dev/null +++ b/bridges/inc/bridges/remote/stub.hxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * $RCSfile: stub.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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 <bridges/remote/remote.hxx> + +#include <uno/dispatcher.h> +#include <uno/mapping.hxx> + +namespace bridges_remote { + +class Uno2RemoteStub : + public remote_Interface +{ +public: + Uno2RemoteStub( uno_Interface *pUnoI, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvUno, + uno_Environment *pEnvRemote ); + ~Uno2RemoteStub(); + + static void SAL_CALL thisAcquire( remote_Interface *pThis ); + static void SAL_CALL thisRelease( remote_Interface *pThis ); + static void SAL_CALL thisDispatch( remote_Interface * pUnoI, + typelib_TypeDescription * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ); + static void SAL_CALL thisFree( uno_ExtEnvironment * pEnvRemote, void *pThis ); + +public: + ::rtl::OUString m_sOid; + typelib_InterfaceTypeDescription *m_pType; + uno_Interface *m_pUnoI; + oslInterlockedCount m_nRef; + + uno_Environment *m_pEnvUno; + uno_Environment *m_pEnvRemote; + ::com::sun::star::uno::Mapping m_mapRemote2Uno; + ::com::sun::star::uno::Mapping m_mapUno2Remote; +}; + +} diff --git a/bridges/prj/d.lst b/bridges/prj/d.lst new file mode 100644 index 000000000000..d4137b83a3ee --- /dev/null +++ b/bridges/prj/d.lst @@ -0,0 +1,26 @@ +mkdir: %_DEST%\inc%_EXT%\bridges +mkdir: %_DEST%\inc%_EXT%\bridges\remote + +..\inc\bridges\remote\connection.h %_DEST%\inc%_EXT%\bridges\remote\connection.h +..\inc\bridges\remote\context.h %_DEST%\inc%_EXT%\bridges\remote\context.h +..\inc\bridges\remote\remote.h %_DEST%\inc%_EXT%\bridges\remote\remote.h + +..\%__SRC%\lib\irmcxt* %_DEST%\lib%_EXT%\* +..\%__SRC%\lib\librmcxt* %_DEST%\lib%_EXT%\* +..\%__SRC%\bin\rmcxt* %_DEST%\bin%_EXT%\* + +..\%__SRC%\lib\libremote_uno* %_DEST%\lib%_EXT%\libremote_uno* +..\%__SRC%\bin\remote_uno* %_DEST%\bin%_EXT%\remote_uno* +..\%__SRC%\lib\liburp_uno* %_DEST%\lib%_EXT%\liburp_uno* +..\%__SRC%\bin\urp_uno* %_DEST%\bin%_EXT%\urp_uno* +..\%__SRC%\lib\libjava_uno* %_DEST%\lib%_EXT%\libjava_uno* +..\%__SRC%\bin\java_uno* %_DEST%\bin%_EXT%\java_uno* +..\%__SRC%\lib\java_uno.jar %_DEST%\bin%_EXT%\java_uno.jar + +..\version.mk %_DEST%\inc%_EXT%\bridges\version.mk + +..\%__SRC%\bin\prot_uno_uno.* %_DEST%\bin%_EXT%\prot_uno_uno.* +..\%__SRC%\bin\msci_uno.* %_DEST%\bin%_EXT%\msci_uno.* +..\%__SRC%\lib\libprot_uno_uno.* %_DEST%\lib%_EXT%\libprot_uno_uno.* +..\%__SRC%\lib\libgcc2_uno.* %_DEST%\lib%_EXT%\libgcc2_uno.* +..\%__SRC%\lib\libsunpro5_uno.* %_DEST%\lib%_EXT%\libsunpro5_uno.* diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/call.s b/bridges/source/cpp_uno/cc50_solaris_intel/call.s new file mode 100644 index 000000000000..826bf03139d2 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_intel/call.s @@ -0,0 +1,212 @@ + .globl privateSnippetExecutor + .align 4 +privateSnippetExecutor: +.L21: + subl $32, %esp + / original %ebx, %eax, %ecx saved by jmp snippet into -12, -16, -20 resp + movl %esp, -24(%ebp) + movl %ecx, -28(%ebp) + + / real code + movl %ebp, %eax + addl $4, %eax + pushl %eax + pushl %ebx / nTablePos + + / set ebx to GOT +.L_GOT_BEGIN: + call .L_GOT_END +.L_GOT_END: + popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-.L_GOT_END],%ebx + + / call collector + call __1cHsunpro5Pcpp_vtable_call6Fippv_v_@PLT +.L22: + movl -28(%ebp), %ecx + cmp $0, %ecx / float + jne .L23 + flds -8(%ebp) + jmp .L29 +.L23: + cmp $1, %ecx / double + jne .L24 + fldl -8(%ebp) + jmp .L29 +.L24: + cmp $2, %ecx / longlong + jne .L25 + movl -4(%ebp), %edx + movl -8(%ebp), %eax + jmp .L29 +.L25: + cmp $3, %ecx / long + jne .L28 + movl -8(%ebp), %eax + jmp .L29 +.L28: + movl -16(%ebp), %eax +.L29: + movl -12(%ebp), %ebx + movl -20(%ebp), %ecx + movl %ebp, %esp + popl %ebp + ret + .type privateSnippetExecutor, @function + .size privateSnippetExecutor, .-privateSnippetExecutor + + .globl privateSnippetExceptionHandler +privateSnippetExceptionHandler: + movl -12(%ebp), %ebx + movl -16(%ebp), %eax + movl -20(%ebp), %ecx + movl -24(%ebp), %esp + call __1cG__CrunMex_rethrow_q6F_v_@PLT + ret + .type privateSnippetExceptionHandler, @function + .size privateSnippetExceptionHandler, .-privateSnippetExceptionHandler + + .align 4 + .globl callVirtualMethod +callVirtualMethod: + pushl %ebp + movl %esp, %ebp + subl $24, %esp + movl %edx, -4(%ebp) + movl %ecx, -8(%ebp) + movl %eax, -12(%ebp) + movl %esp, -16(%ebp) + movl %ebx, -20(%ebp) + + / set ebx to GOT +.L_GOT_BEGIN_2: + call .L_GOT_END_2 +.L_GOT_END_2: + popl %ebx + addl $_GLOBAL_OFFSET_TABLE_+[.-.L_GOT_END_2],%ebx +.callBeginPosition: + movl 28(%ebp), %eax + movl %eax, %edx + dec %edx + shl $2, %edx + add 24(%ebp), %edx +.copyLong: + movl 0(%edx), %ecx + sub $4, %edx + push %ecx + dec %eax + jne .copyLong +.doCall: + movl 8(%ebp), %edx + movl 0(%edx), %edx + movl 12(%ebp), %eax + add $2, %eax + shl $2, %eax + add %eax, %edx + movl 0(%edx), %edx + + call *%edx + +.callVirtualMethodExceptionPosition: + / handle returns + movl 20(%ebp), %ecx + + / byte types + cmp $2, %ecx / typelib_TypeClass_BOOLEAN + je .handleByte + cmp $3, %ecx + je .handleByte / typelib_TypeClass_BYTE + + / half word types + cmp $4, %ecx / typelib_TypeClass_SHORT + je .handleShort + cmp $5, %ecx / typelib_TypeClass_UNSIGNED_SHORT + je .handleShort + + / word types + cmp $6, %ecx / typelib_TypeClass_LONG + je .handleWord + cmp $7, %ecx / typelib_TypeClass_UNSIGNED_LONG + je .handleWord + cmp $1, %ecx / typelib_TypeClass_CHAR (wchar_t) + je .handleWord + cmp $15, %ecx / typelib_TypeClass_ENUM + je .handleWord + + / double word types + cmp $8, %ecx / typelib_TypeClass_HYPER + je .handleDoubleWord + cmp $9, %ecx / typelib_TypeClass_UNSIGNED_HYPER + je .handleDoubleWord + + / float + cmp $10, %ecx / typelib_TypeClass_FLOAT + je .handleFloat + + / double + cmp $11, %ecx / typelib_TypeClass_DOUBLE + je .handleDouble + + / default: return void + jmp .doRestore +.handleByte: + movl 16(%ebp), %ecx + movb %al, 0(%ecx) + jmp .doRestore +.handleShort: + movl 16(%ebp), %ecx + movw %ax, 0(%ecx) + jmp .doRestore +.handleWord: + movl 16(%ebp), %ecx + movl %eax, 0(%ecx) + jmp .doRestore +.handleDoubleWord: + movl 16(%ebp), %ecx + movl %eax, 0(%ecx) + movl %edx, 4(%ecx) + jmp .doRestore +.handleFloat: + movl 16(%ebp), %ecx + fstps 0(%ecx) + jmp .doRestore +.handleDouble: + movl 16(%ebp), %ecx + fstpl 0(%ecx) + jmp .doRestore +.doRestore: + movl -4(%ebp), %edx + movl -8(%ebp), %ecx + movl -12(%ebp), %eax + movl -20(%ebp), %ebx + movl %ebp, %esp + popl %ebp + ret + .type callVirtualMethod, @function + .size callVirtualMethod, .-callVirtualMethod + + .globl callVirtualMethodExceptionHandler +callVirtualMethodExceptionHandler: + movl -4(%ebp), %edx + movl -8(%ebp), %ecx + movl -12(%ebp), %eax + movl -16(%ebp), %esp + movl -20(%ebp), %ebx + call __1cG__CrunMex_rethrow_q6F_v_@PLT + ret + + .type callVirtualMethodExceptionHandler, @function + .size callVirtualMethodExceptionHandler, .-callVirtualMethodExceptionHandler + + + .section .exception_ranges,"aw" + .align 4 + + .4byte .L21@rel + .4byte .L22-.L21 + .4byte privateSnippetExceptionHandler-.L21 + .zero 8 + .4byte .callBeginPosition@rel + .4byte .callVirtualMethodExceptionPosition-.callBeginPosition + .4byte callVirtualMethodExceptionHandler-.callBeginPosition + .zero 8 diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx b/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx new file mode 100644 index 000000000000..25d89a8538ed --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_intel/cc50_solaris_intel.hxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * $RCSfile: cc50_solaris_intel.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif +#include <typeinfo> + +typedef struct _uno_Any uno_Any; +typedef struct _uno_Mapping uno_Mapping; + +// private C50 structures and functions +namespace __Crun +{ + struct static_type_info + { + char* m_pClassName; + int m_nSkip1; // must be 0 + void* m_pMagic; // points to some magic data + int m_nMagic[ 4 ]; + int m_nSkip2[2]; // must be 0 + }; + void* ex_alloc(unsigned); + void ex_throw( void*, const static_type_info*, void(*)(void*)); + void* ex_get(); + void ex_rethrow_q(); +} + +namespace __Cimpl +{ + const char* ex_name(); +} + +extern "C" void _ex_register( void*, int ); + +namespace CPPU_CURRENT_NAMESPACE +{ + +//################################################################################################## +//#### exceptions ################################################################################## +//################################################################################################## + +void cc50_solaris_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ); +void cc50_solaris_intel_fillUnoException( void*, const char*, uno_Any*, uno_Mapping * pCpp2Uno ); + +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx new file mode 100644 index 000000000000..25d1d87391a5 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_intel/cpp2uno.cxx @@ -0,0 +1,637 @@ +/************************************************************************* + * + * $RCSfile: cpp2uno.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#define LEAK_STATIC_DATA +// #define TRACE(x) OSL_TRACE(x) +#define TRACE(x) + +#include <alloca.h> +#include <stl/list> +#include <stl/map> + +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ +#include <typelib/typedescription.hxx> +#endif +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ +#include <bridges/cpp_uno/type_misc.hxx> +#endif + +#include "cc50_solaris_intel.hxx" + +using namespace com::sun::star::uno; +using namespace std; +using namespace osl; +using namespace rtl; + +extern "C" +{ + void privateSnippetExecutor(); +} + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +static inline 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: [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_ENSHURE( 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 ] = 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 no 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 ); + + cc50_solaris_intel_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 inline typelib_TypeClass cpp_mediate( + sal_Int32 nVtableCall, + void ** pCallStack, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + OSL_ENSHURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); + + // pCallStack: this, params + // _this_ ptr is patched cppu_Interface 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_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, + "### illegal vtable index!" ); + if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) + { + throw RuntimeException( OUString::createFromAscii("illegal vtable index!"), (XInterface *)pCppI ); + } + + // determine called method + OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; + OSL_ENSHURE( 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) + { + // standard XInterface vtable calls + 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() ); + OSL_ASSERT( 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; +} + + +//================================================================================================== +class MediateClassData +{ +public: + struct ClassDataBuffer + { + void** m_pVTable; + + ~ClassDataBuffer(); + }; +private: + + map< OUString, ClassDataBuffer* > m_aClassData; + Mutex m_aMutex; + + void createVTable( ClassDataBuffer*, typelib_InterfaceTypeDescription* ); +public: + const ClassDataBuffer* getClassData( typelib_InterfaceTypeDescription* ); + + MediateClassData() {} + ~MediateClassData(); +}; +//__________________________________________________________________________________________________ + +MediateClassData::ClassDataBuffer::~ClassDataBuffer() +{ + delete m_pVTable; +} + +//__________________________________________________________________________________________________ +MediateClassData::~MediateClassData() +{ + TRACE( "> calling ~MediateClassData(): freeing mediate vtables... <\n" ); + + // this MUST be the absolute last one which is called! + for ( map< OUString, ClassDataBuffer* >::iterator iPos( m_aClassData.begin() ); iPos != m_aClassData.end(); ++iPos ) + { + // todo +// delete (*iPos).second; + } +} + +//__________________________________________________________________________________________________ + +const MediateClassData::ClassDataBuffer* MediateClassData::getClassData( typelib_InterfaceTypeDescription* pType ) +{ + MutexGuard aGuard( m_aMutex ); + + map< OUString, ClassDataBuffer* >::iterator element = m_aClassData.find( pType->aBase.pTypeName ); + if( element != m_aClassData.end() ) + return (*element).second; + + ClassDataBuffer* pBuffer = new ClassDataBuffer(); + createVTable( pBuffer, pType ); + m_aClassData[ pType->aBase.pTypeName ] = pBuffer; + return pBuffer; +} + +//================================================================================================== +void cpp_vtable_call( int nTableEntry, void** pCallStack ) +{ + cpp_mediate( nTableEntry, pCallStack, (sal_Int64*)(pCallStack - 3) ); +} + +enum SpecialReturnType { ReturnVoid, ReturnFloat, ReturnDouble, ReturnLong, ReturnLongLong }; + +//__________________________________________________________________________________________________ +void MediateClassData::createVTable( ClassDataBuffer* pBuffer, typelib_InterfaceTypeDescription* pType ) +{ + // get all member functions + list< SpecialReturnType > aSpecialReturn; + list< sal_Bool > aComplexReturn; + + for( int n = 0; n < pType->nAllMembers; n++ ) + { + typelib_TypeDescription* pMember = NULL; + TYPELIB_DANGER_GET( &pMember, pType->ppAllMembers[n] ); + if( pMember->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE ) + { + typelib_TypeDescription * pRetTD = 0; + TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceAttributeTypeDescription *)pMember)->pAttributeTypeRef ); + // get method + switch( pRetTD->eTypeClass ) + { + case typelib_TypeClass_FLOAT: + aSpecialReturn.push_back( ReturnFloat ); + break; + case typelib_TypeClass_DOUBLE: + aSpecialReturn.push_back( ReturnDouble ); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + aSpecialReturn.push_back( ReturnLongLong ); + break; + default: + aSpecialReturn.push_back( ReturnLong ); + break; + } + aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); + // set method + if( ! ((typelib_InterfaceAttributeTypeDescription*)pMember)->bReadOnly ) + { + aSpecialReturn.push_back( ReturnVoid ); + aComplexReturn.push_back( sal_False ); + } + TYPELIB_DANGER_RELEASE( pRetTD ); + } + else + { + typelib_TypeDescription * pRetTD = 0; + TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceMethodTypeDescription *)pMember)->pReturnTypeRef ); + switch( pRetTD->eTypeClass ) + { + case typelib_TypeClass_FLOAT: + aSpecialReturn.push_back( ReturnFloat ); + break; + case typelib_TypeClass_DOUBLE: + aSpecialReturn.push_back( ReturnDouble ); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + aSpecialReturn.push_back( ReturnLongLong ); + break; + case typelib_TypeClass_VOID: + aSpecialReturn.push_back( ReturnVoid ); + break; + default: + aSpecialReturn.push_back( ReturnLong ); + break; + } + aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); + TYPELIB_DANGER_RELEASE( pRetTD ); + } + TYPELIB_DANGER_RELEASE( pMember ); + } + + const int nSnippetSize = 256; + int nSize = aSpecialReturn.size(); + char * pSpace = (char *)rtl_allocateMemory( ((nSize+3)*sizeof(void *)) + (nSize * nSnippetSize) ); + pBuffer->m_pVTable = (void**)pSpace; + + char * pCode = pSpace + ((nSize+3)*sizeof(void *)); + void ** pvft = (void **)pSpace; + pvft[0] = NULL; // RTTI + pvft[1] = NULL; // null + pvft[2] = NULL; // destructor + + // setup vft and code + for ( sal_Int32 nPos = 0; nPos < nSize; ++nPos ) + { + unsigned char * codeSnip = + (unsigned char*)((unsigned char *)pCode + (nPos*nSnippetSize)); + SpecialReturnType eRet = aSpecialReturn.front(); + aSpecialReturn.pop_front(); + long nTablePos = nPos; + if( aComplexReturn.front() ) + nTablePos |= 0x80000000; + aComplexReturn.pop_front(); + pvft[nPos+3] = codeSnip; + /*generate this code: + * pushl %ebp + * movl %esp, %ebp + * movl %eax, -20(%esp) + * movl %ebx, -16(%esp) + * movl %ecx, -24(%esp) + * movl $nTablePos, %ebx + * movl $<return type>, %ecx + * jmp privateSnippetExecutor + */ + *codeSnip++ = 0x55; // pushl %ebp + *codeSnip++ = 0x8b; // movl %esp, %ebp + *codeSnip++ = 0xec; + *codeSnip++ = 0x89; // movl %eax, -16(%ebp) + *codeSnip++ = 0x45; + *codeSnip++ = 0xf0; + *codeSnip++ = 0x89; // movl %ebx, -12(%ebp) + *codeSnip++ = 0x5d; + *codeSnip++ = 0xf4; + *codeSnip++ = 0x89; // movl %ecx, -20(%ebp) + *codeSnip++ = 0x4d; + *codeSnip++ = 0xec; + + *codeSnip++ = 0xbb; // movl $nTablePos, %ebx + *((long*)codeSnip) = nTablePos; + codeSnip += sizeof(long); + *codeSnip++ = 0xb9; // movl <return type>, %ecx + switch( eRet ) + { + case ReturnFloat: *((long*)codeSnip) = 0;break; + case ReturnDouble: *((long*)codeSnip) = 1;break; + case ReturnLong: *((long*)codeSnip) = 3;break; + case ReturnLongLong: *((long*)codeSnip) = 2;break; + case ReturnVoid: + default: *((long*)codeSnip) = 4;break; + } + codeSnip += sizeof(long); + *codeSnip++ = 0xe9; // jmp privateSnippetExecutor + *((long*)codeSnip) = ((unsigned char *)privateSnippetExecutor) - codeSnip - sizeof(long); + codeSnip += sizeof(long); + } +} + +//================================================================================================== +void SAL_CALL cppu_cppInterfaceProxy_patchVtable( + XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + 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 + } + } + *(const void **)pCppI = s_pMediateClassData->getClassData( pTypeDescr )->m_pVTable + 1; +} + +} + +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) +{ + CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( pCppEnv ); +} +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_ext_getMapping( + uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) +{ + CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( ppMapping, pFrom, pTo ); +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx new file mode 100644 index 000000000000..f5903a694a83 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_intel/except.cxx @@ -0,0 +1,453 @@ +/************************************************************************* + * + * $RCSfile: except.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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 <dlfcn.h> +#include <new.h> +#include <typeinfo> +#include <stl/list> +#include <stl/map> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ +#include <typelib/typedescription.hxx> +#endif +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#include "cc50_solaris_intel.hxx" + +// need a += operator for OString and sal_Char +namespace rtl +{ + inline OString& operator+=( OString& rString, sal_Char cAdd ) + { + sal_Char add[2]; + add[0] = cAdd; + add[1] = 0; + return rString += add; + } +} + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +static OString toUNOname( const OString & rRTTIname ) +{ + OString aRet; + + const sal_Char* pRTTI = rRTTIname.getStr(); + const sal_Char* pOrg = pRTTI; + const sal_Char* pLast = pRTTI; + + while( 1 ) + { + if( *pRTTI == ':' || *pRTTI == 0 ) + { + if( aRet.getLength() ) + aRet += "."; + aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast ); + while( *pRTTI == ':' ) + pRTTI++; + pLast = pRTTI; + if( ! *pRTTI ) + break; + } + else + pRTTI++; + } + + return aRet; +} +//================================================================================================== +static OString toRTTIname( const OString & rUNOname ) +{ + OString aRet; + + int nTokens = rUNOname.getTokenCount( '.' ); + for( int i = 0; i < nTokens; i++ ) + { + if( i > 0 ) + aRet += "::"; + aRet += rUNOname.getToken( i, '.' ); + } + + return aRet; +} +//================================================================================================== + +static int replaceQdDdD( const OString& rIn, OString& rOutdD, OString& rOutdDdD ) +{ + int nRet = 0; + int nLen = rIn.getLength(), i, n; + rOutdD = OString(); + rOutdDdD = OString(); + for( i = 0, n = 0; ( i = rIn.indexOf( 'Q', i ) ) != -1 && i < nLen; i++ ) + { + rOutdD += rIn.copy( n, i-n+1 ); + rOutdDdD += rIn.copy( n, i-n+1 ); + n = i+1; + rOutdD += "dD"; + rOutdDdD += "dDdD"; + nRet++; + } + rOutdD += rIn.copy( n ); + rOutdDdD += rIn.copy( n ); + return nRet; +} + +static OString toRTTIsymbolname( const OString & rRTTIname ) +{ + if( ! rRTTIname.getLength() ) + return OString(); + + OString aRet; + OString aPrefix; + + int nUnoTokens = rRTTIname.getTokenCount( ':' ); + int nAdjust = 0; + for( int i = 0; i < nUnoTokens; i++ ) + { + OString aToken( rRTTIname.getToken( i, ':' ) ); + int nBytes = aToken.getLength(); + if( nBytes ) + { + OString aAdd; + if( nBytes > 25 ) + { + aAdd += (sal_Char)( nBytes/26 + 'a' ); + aAdd += (sal_Char)( nBytes % 26 + 'A' ); + } + else + aAdd += (sal_Char)( nBytes + 'A' ); + aRet += aAdd; + // special case "Q" + if( ( ( nBytes % 26 ) +'A' ) == 'Q' ) + { + aRet += "dD"; + nAdjust += 2; + } + + OString adD, adDdD; + int nRepl = replaceQdDdD( aToken, adD, adDdD ); + if( nUnoTokens == 1 ) + { + // must replace "Q" by "QdD" + aRet += adD; + nAdjust += 2* nRepl; + } + else + { + // must replace "Q" by "QdDdD" + aRet += adDdD; + nAdjust += 4* nRepl; + } + + if( i < nUnoTokens - 1 ) + { + aPrefix += aAdd; + // must replace "Q" by "QdD" + aPrefix += adD; + } + } + } + aRet += '_'; + + if( aPrefix.getLength() ) + { + int nBytes = aRet.getLength() - nAdjust + 10; + if( nBytes > 25 ) + { + aPrefix += (sal_Char)( nBytes/26 + 'a' ); + aPrefix += (sal_Char)( nBytes % 26 + 'A' ); + } + else + aPrefix += (sal_Char)( nBytes + 'A' ); + + + aRet = "__1c" + aPrefix + "__RTTI__1n" + aRet + "_"; + } + else + aRet = "__RTTI__1n"+aRet; + + return aRet; +} + +//################################################################################################## +//#### RTTI simulation ############################################################################# +//################################################################################################## + +class RTTIHolder +{ + static std::map< OString, void* > aAllRTTI; +public: + static void* getRTTI( const OString& rTypename ); + static void* getRTTI_UnoName( const OString& rUnoTypename ) + { return getRTTI( toRTTIname( rUnoTypename ) ); } + + static void* insertRTTI( const OString& rTypename ); + static void* insertRTTI_UnoName( const OString& rTypename ) + { return insertRTTI( toRTTIname( rTypename ) ); } + + // rSuperTypename MUST exist !!! + static void* insertRTTI( const OString& rTypename, const OString& rSuperTypename ); + static void* insertRTTI_UnoNames( const OString& rTypename, const OString& rSuperTypename ) + { return insertRTTI( toRTTIname( rTypename ), toRTTIname( rSuperTypename ) ); } + +}; + +std::map< OString, void* > RTTIHolder::aAllRTTI; + +void* RTTIHolder::getRTTI( const OString& rTypename ) +{ + std::map< OString, void* >::iterator element; + + element = aAllRTTI.find( rTypename ); + if( element != aAllRTTI.end() ) + return (*element).second; + // create new rtti + // first look for existing type info function + static void* pMain = dlopen( NULL, RTLD_NOW ); + + void* pSymbol = dlsym( pMain, toRTTIsymbolname( rTypename ).getStr() ); + if( pSymbol ) + { + // there exists type info, use it (otherwise it will not be equal + // since addresses - not contents - are matched in RTTI compare) + aAllRTTI[ rTypename ] = pSymbol; + return pSymbol; + } + // no type found + return NULL; +} + +static long nMagicId = 1; + +void* RTTIHolder::insertRTTI( const OString& rTypename ) +{ + void** pRTTI = new void*[ 19 ]; + memset( pRTTI, 0, 19*sizeof( void* ) ); + pRTTI[ 0 ] = (void*)strdup( rTypename.getStr() ); + pRTTI[ 2 ] = (void*)(7*sizeof(void*)); + pRTTI[ 3 ] = (void*)nMagicId++; + pRTTI[ 4 ] = (void*)nMagicId++; + pRTTI[ 5 ] = (void*)nMagicId++; + pRTTI[ 6 ] = (void*)nMagicId++; + + pRTTI[ 9 ] = pRTTI[ 3 ]; + pRTTI[ 10 ] = pRTTI[ 4 ]; + pRTTI[ 11 ] = pRTTI[ 5 ]; + pRTTI[ 12 ] = pRTTI[ 6 ]; + pRTTI[ 13 ] = (void*)0x80000000; + + aAllRTTI[ rTypename ] = (void*)pRTTI; + return pRTTI; +} + +void* RTTIHolder::insertRTTI( const OString& rTypename, const OString& rSuperTypename ) +{ + OSL_ENSHURE( ! getRTTI( rTypename ), "insert RTTI called on already existing type" ); + + void** pBaseRTTI = (void**)getRTTI( rSuperTypename ); + OSL_ENSHURE( pBaseRTTI, "insert RTTI called with nonexisting supertype" ); + + std::list< void* > aSuperTypes; + + void** pTypeList = pBaseRTTI + 2 + ((int)pBaseRTTI[2] / sizeof(void*)); + while( *pTypeList != (void*)0x80000000 ) + aSuperTypes.push_back( *pTypeList++ ); + + void** pRTTI = new void*[ 8 + aSuperTypes.size()+1 ]; + memset( pRTTI, 0, (8 + aSuperTypes.size()+1 + 5)*sizeof(void*)); + pRTTI[ 0 ] = (void*)strdup( rTypename.getStr() ); + pRTTI[ 2 ] = (void*)(7*sizeof(void*)); + pRTTI[ 3 ] = (void*)nMagicId++; + pRTTI[ 4 ] = (void*)nMagicId++; + pRTTI[ 5 ] = (void*)nMagicId++; + pRTTI[ 6 ] = (void*)nMagicId++; + + int nPos = 9; + while( aSuperTypes.size() ) + { + pRTTI[ nPos++ ] = aSuperTypes.front(); + aSuperTypes.pop_front(); + } + pRTTI[ nPos++ ] = 0; + pRTTI[ nPos++ ] = pRTTI[ 3 ]; + pRTTI[ nPos++ ] = pRTTI[ 4 ]; + pRTTI[ nPos++ ] = pRTTI[ 5 ]; + pRTTI[ nPos++ ] = pRTTI[ 6 ]; + pRTTI[ nPos ] = (void*)0x80000000; + + aAllRTTI[ rTypename ] = pRTTI; + return pRTTI; +} + +//-------------------------------------------------------------------------------------------------- + +static void* generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr ) +{ + OString aCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + + void* pRTTI = RTTIHolder::getRTTI_UnoName( aCompTypeName ); + if( pRTTI ) + return pRTTI; + + if( ! pCompTypeDescr->pBaseTypeDescription ) + // this is a base type + return RTTIHolder::insertRTTI_UnoName( aCompTypeName ); + // generate super rtti if necessary + void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription ); + OSL_ENSHURE( pSuperRTTI, "could not generate RTTI for supertype!" ); + + return RTTIHolder::insertRTTI_UnoNames( + aCompTypeName, + OUStringToOString( pCompTypeDescr->pBaseTypeDescription->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) + ); +} + +//-------------------------------------------------------------------------------------------------- + +static std::map< void*, typelib_TypeDescription* > aExceptionMap; + +static void deleteException( void* pExc ) +{ + std::map< void*, typelib_TypeDescription* >::iterator element = + aExceptionMap.find( pExc ); + if( element != aExceptionMap.end() ) + { + typelib_TypeDescription* pType = (*element).second; + aExceptionMap.erase( pExc ); + uno_destructData( pExc, pType, cpp_release ); + typelib_typedescription_release( pType ); + } +} + +//__________________________________________________________________________________________________ + +//################################################################################################## +//#### exported #################################################################################### +//################################################################################################## + + +void cc50_solaris_intel_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +{ + // construct cpp exception object + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType ); + + void * pCppExc = __Crun::ex_alloc( pTypeDescr->nSize ); // will be released in generated dtor + uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); + + // destruct uno exception + uno_any_destruct( pUnoExc, 0 ); + + // a must be + OSL_ENSHURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" ); + + typelib_CompoundTypeDescription * pCompTypeDescr = (typelib_CompoundTypeDescription *)pTypeDescr; + void* pRTTI = generateRTTI( pCompTypeDescr ); + + TYPELIB_DANGER_RELEASE( pTypeDescr ); + + __Crun::ex_throw( pCppExc, (const __Crun::static_type_info*)pRTTI, deleteException ); +} + +void cc50_solaris_intel_fillUnoException( + void* pCppExc, + const char* pInfo, + uno_Any* pExc, + uno_Mapping * pCpp2Uno ) +{ + OUString aName( OStringToOUString( toUNOname( pInfo ), RTL_TEXTENCODING_ASCII_US ) ); + typelib_TypeDescription * pExcTypeDescr = 0; + typelib_typedescription_getByName( + &pExcTypeDescr, + aName.pData ); + if (pExcTypeDescr) + { + // 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 ); + } +} + +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk b/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk new file mode 100644 index 000000000000..edc4410ba4b9 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_intel/makefile.mk @@ -0,0 +1,110 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ +# +# 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=cppu +TARGET=sunpro5_uno +LIBTARGET=no +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +.IF "$(COM)$(CPU)" == "C50I" + +CFLAGS += -O5 -xO5 + +SLOFILES= \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj \ + $(SLO)$/except.obj \ + $(SLO)$/call.obj + +SHL1TARGET= $(TARGET) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB= i$(TARGET) + +SHL1OBJS= \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj \ + $(SLO)$/except.obj \ + $(SLO)$/call.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) + +.ENDIF + +.INCLUDE : target.mk + +$(SLO)$/call.obj: call.s + CC -c -o $(SLO)$/call.o call.s ; touch $(SLO)$/call.obj + diff --git a/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx b/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx new file mode 100644 index 000000000000..11f2899b22f3 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_intel/uno2cpp.cxx @@ -0,0 +1,444 @@ +/************************************************************************* + * + * $RCSfile: uno2cpp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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 <alloca.h> +#include <stl/map> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif + +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ +#include <bridges/cpp_uno/type_misc.hxx> +#endif + +#include "cc50_solaris_intel.hxx" + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +extern "C" { + void callVirtualMethod( + void * pThis, + sal_Int32 nVtableIndex, + void * pRegisterReturn, + typelib_TypeClass eReturnType, + sal_Int32 * pStackLongs, + sal_Int32 nStackLongs + ); +} + +//================================================================================================== +static inline void cpp_call( cppu_unoInterfaceProxy * pThis, + sal_Int32 nVtableCall, + typelib_TypeDescriptionReference * pReturnTypeRef, + sal_Int32 nParams, typelib_MethodParameter * pParams, + sal_Int32 nExceptions, typelib_TypeDescriptionReference ** ppExceptionRefs, + void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) +{ + // max space for: [complex ret ptr], values|ptr ... + char * pCppStack = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) ); + char * pCppStackStart = pCppStack; + + // return + typelib_TypeDescription * pReturnTypeDescr = 0; + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + OSL_ENSHURE( pReturnTypeDescr, "### expected return type description!" ); + + void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion + + long return_buffer[64]; + void * pReturnSpace = 0; + + if (pReturnTypeDescr) + { + if (cppu_isSimpleType( pReturnTypeDescr )) + { + pCppReturn = pUnoReturn; // direct way for simple types + } + else + { + // complex return via ptr + pCppReturn = *(void **)pCppStack = + (cppu_relatesToInterface( pReturnTypeDescr ) + ? (pReturnTypeDescr->nSize > sizeof(return_buffer) ? (pReturnSpace = rtl_allocateMemory( pReturnTypeDescr->nSize )) : return_buffer) + : pUnoReturn); // direct way + pCppStack += sizeof(void *); + } + } + // push this + *(void**)pCppStack = pThis->pCppI; + pCppStack += sizeof( void* ); + + const int nMaxParams = 32; + // args + void * args_buffer[3 * nMaxParams]; + void ** pCppArgs = (void **)(nParams > nMaxParams ? rtl_allocateMemory( 3 * sizeof(void *) * nParams ) : args_buffer); + // 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; + + const int nTempBufferSize = 256; + sal_Int32 nTempBufferPos = 0; + long params_buffer[nTempBufferSize]; + + 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 )) + { + pCppArgs[ nPos ] = pCppStack; + uno_copyAndConvertData( pCppArgs[nPos], 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! + if (pParamTypeDescr->nSize > (sizeof(long) * (nTempBufferSize - nTempBufferPos))) + { + uno_constructData( + *(void **)pCppStack = pCppArgs[nPos] = rtl_allocateMemory( pParamTypeDescr->nSize ), + pParamTypeDescr ); + pTempIndizes[nTempIndizes] = nPos | 0x80000000; // default constructed for cpp call + } + else + { + uno_constructData( + *(void **)pCppStack = pCppArgs[nPos] = (params_buffer + nTempBufferPos), + pParamTypeDescr ); + pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call + nTempBufferPos += (pParamTypeDescr->nSize / sizeof(long)) +1; + } + // will be released at reconversion + ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr; + } + // is in/inout + else if (cppu_relatesToInterface( pParamTypeDescr )) + { + if (pParamTypeDescr->nSize > (sizeof(long)*(nTempBufferSize - nTempBufferPos))) + { + uno_copyAndConvertData( + *(void **)pCppStack = pCppArgs[nPos] = rtl_allocateMemory( pParamTypeDescr->nSize ), + pUnoArgs[nPos], pParamTypeDescr, &pThis->pBridge->aUno2Cpp ); + pTempIndizes[nTempIndizes] = nPos | 0x80000000; // has to be reconverted + } + else + { + uno_copyAndConvertData( + *(void **)pCppStack = pCppArgs[nPos] = (params_buffer + nTempBufferPos), + pUnoArgs[nPos], pParamTypeDescr, &pThis->pBridge->aUno2Cpp ); + pTempIndizes[nTempIndizes] = nPos; // has to be reconverted + nTempBufferPos += (pParamTypeDescr->nSize / sizeof(long)) +1; + } + // 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 + { + int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32); + if( nStackLongs & 1 ) + // stack has to be 8 byte aligned + nStackLongs++; + + callVirtualMethod( + pThis->pCppI, + nVtableCall, + pCppReturn, + pReturnTypeDescr->eTypeClass, + (sal_Int32 *)pCppStackStart, + nStackLongs + ); + + // NO exception occured... + *ppUnoExc = 0; + + // reconvert temporary params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + sal_Bool bAllocated = (nIndex & 0x80000000) != 0; + nIndex &= 0x7fffffff; + 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 ); + + if (bAllocated) + rtl_freeMemory( pCppArgs[nIndex] ); + 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( ... ) + { + // get exception + cc50_solaris_intel_fillUnoException( __Crun::ex_get(), + __Cimpl::ex_name(), + *ppUnoExc, + &pThis->pBridge->aCpp2Uno ); + // temporary params + for ( ; nTempIndizes--; ) + { + sal_Int32 nIndex = pTempIndizes[nTempIndizes]; + sal_Bool bAllocated = (nIndex & 0x80000000) != 0; + nIndex &= 0x7fffffff; + // destroy temp cpp param => cpp: every param was constructed + uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release ); + if (bAllocated) + rtl_freeMemory( pCppArgs[nIndex] ); + TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] ); + } + // return type + if (pReturnTypeDescr) + TYPELIB_DANGER_RELEASE( pReturnTypeDescr ); + } + + if (pCppArgs != (void **)args_buffer) + rtl_freeMemory( pCppArgs ); + if (pReturnSpace) + rtl_freeMemory( pReturnSpace ); +} + +//================================================================================================== +void SAL_CALL cppu_unoInterfaceProxy_dispatch( + uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr, + void * pReturn, void * pArgs[], uno_Any ** ppException ) +{ + // 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_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); + + sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos]; + OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + + typelib_TypeDescriptionReference * pRuntimeExcRef = 0; + + if (pReturn) + { + // dependent dispatch + cpp_call( pThis, nVtableCall, + ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, + 0, 0, // no params + 1, &pRuntimeExcRef, // RuntimeException + 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, + 1, &pRuntimeExcRef, + 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_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); + + sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos]; + OSL_ENSHURE( 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() ); + OSL_ASSERT( 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, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nExceptions, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->ppExceptions, + pReturn, pArgs, ppException ); + } + break; + } + default: + { + ::com::sun::star::uno::RuntimeException aExc; + aExc.Message = OUString::createFromAscii("illegal member type description!"); + aExc.Context = pThis->pCppI; + + typelib_TypeDescription * pTD = 0; + const Type & rExcType = ::getCppuType( (const ::com::sun::star::uno::RuntimeException *)0 ); + TYPELIB_DANGER_GET( &pTD, rExcType.getTypeLibType() ); + uno_any_construct( *ppException, &aExc, pTD, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + } + } +} + +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/call.s b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s new file mode 100644 index 000000000000..b8fa60af3989 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/call.s @@ -0,0 +1,165 @@ +.global callVirtualMethod +.type callVirtualMethod,2 +callVirtualMethod: + ! allocate FIRST stack to have own local registers + save %sp, -96, %sp + ! copy in to out parameters for second stackframe + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + mov %i3, %o3 + mov %i4, %o4 + mov %i5, %o5 + + ! decide wether there are more than 6 parameter + mov -96, %l3 ! default stack space + subcc %i5, 6, %l5 + ble allocateSecondStack + nop + sll %l5, 2, %l5 + sub %l3, %l5, %l3 +allocateSecondStack: + save %sp, %l3, %sp ! allocate new stack + ! copy stack longs if necessary + subcc %i5, 6, %l5 + ble copyRegisters + nop + + ! prepare source location + add %i4, 24, %l4 + + ! prepare real stack + add %sp, 92, %l3 + +copyLong: + ld [%l4+0], %l0 + st %l0, [%l3] + add %l4, 4, %l4 + add %l3, 4, %l3 + deccc %l5 + bne copyLong + nop +copyRegisters: + mov %i5, %l5 + mov %i4, %l4 + + ld [%l4], %o0 + add %l4, 4, %l4 + deccc %l5 + ble doCall + + ld [%l4], %o1 + add %l4, 4, %l4 + deccc %l5 + ble doCall + + ld [%l4], %o2 + add %l4, 4, %l4 + deccc %l5 + ble doCall + + ld [%l4], %o3 + add %l4, 4, %l4 + deccc %l5 + ble doCall + + ld [%l4], %o4 + add %l4, 4, %l4 + deccc %l5 + ble doCall + + ld [%l4], %o5 + add %l4, 4, %l4 + + ! prepare complex return pointer + st %i2, [%sp+64] +doCall: + ! get virtual table entry + mov %i1, %l1 + add %l1, 2, %l1 + sll %l1, 2, %l1 + ld [%i0], %l3 + add %l3, %l1, %l1 + ld [%l1], %l0 + jmpl %l0,%o7 + nop +.global callVirtualMethodExceptionHandler +.type callVirtualMethodExceptionHandler,2 +callVirtualMethodExceptionHandler: + ! handle returns + + !byte types + subcc %i3, 2, %l3 ! typelib_TypeClass_BOOLEAN + be handleByte + subcc %i3, 3, %l3 ! typelib_TypeClass_BYTE + be handleByte + + ! half word types + subcc %i3, 4, %l3 ! typelib_TypeClass_SHORT + be handleShort + subcc %i3, 5, %l3 ! typelib_TypeClass_UNSIGNED_SHORT + be handleShort + subcc %i3, 1, %l3 ! typelib_TypeClass_CHAR (sal_Unicode==sal_uInt16) + be handleShort + + ! word types + subcc %i3, 6, %l3 ! typelib_TypeClass_LONG + be handleWord + subcc %i3, 7, %l3 ! typelib_TypeClass_UNSIGNED_LONG + be handleWord + subcc %i3, 15, %l3 ! typelib_TypeClass_ENUM + be handleWord + + ! double word types + subcc %i3, 8, %l3 ! typelib_TypeClass_HYPER + be handleDoubleWord + subcc %i3, 9, %l3 ! typelib_TypeClass_UNSIGNED_HYPER + be handleDoubleWord + + ! float + subcc %i3, 10, %l3 ! typelib_TypeClass_FLOAT + be handleFloat + + ! double + subcc %i3, 11, %l3 ! typelib_TypeClass_DOUBLE + be handleDouble + + ! default: return void + nop ! empty prefetch + ba doRestore + nop +handleByte: + stb %o0, [%i2] + ba doRestore + nop +handleShort: + sth %o0, [%i2] + ba doRestore + nop +handleWord: + st %o0, [%i2] + ba doRestore + nop +handleDoubleWord: + st %o0, [%i2] + st %o1, [%i2+4] + ba doRestore + nop +handleFloat: + st %f0, [%i2] + ba doRestore + nop +handleDouble: + std %f0, [%fp-8] + ldd [%fp-8], %o0 + st %o0, [%i2] + st %o1, [%i2+4] + ba doRestore + nop +doRestore: + restore ! stack frame for called method + ret + restore ! stack frame for own locals +.size callVirtualMethodExceptionHandler,(.-callVirtualMethodExceptionHandler) +.size callVirtualMethod,(.-callVirtualMethod) +.align 8
\ No newline at end of file diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx new file mode 100644 index 000000000000..4dd06177a346 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cc50_solaris_sparc.hxx @@ -0,0 +1,118 @@ +/************************************************************************* + * + * $RCSfile: cc50_solaris_sparc.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif +#include <typeinfo> + +typedef struct _uno_Any uno_Any; +typedef struct _uno_Mapping uno_Mapping; + +// private C50 structures and functions +namespace __Crun +{ + struct static_type_info + { + char* m_pClassName; + int m_nSkip1; // must be 0 + void* m_pMagic; // points to some magic data + int m_nMagic[ 4 ]; + int m_nSkip2[2]; // must be 0 + }; + void* ex_alloc(unsigned); + void ex_throw( void*, const static_type_info*, void(*)(void*)); + void* ex_get(); + void ex_rethrow_q() throw(); +} + +namespace __Cimpl +{ + const char* ex_name(); +} + +extern "C" void _ex_register( void*, int ); + +namespace CPPU_CURRENT_NAMESPACE +{ + +inline char* adjustPointer( char* pIn, typelib_TypeDescription* pType ) +{ + switch( pType->nSize ) + { + case 1: return pIn + 3; + case 2: return pIn + 2; + case 3: return pIn + 1; + // Huh ? perhaps a char[3] ? Though that would be a pointer + // well, we have it anyway for symmetry + } + return pIn; +} + +//################################################################################################## +//#### exceptions ################################################################################## +//################################################################################################## + +void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ); +void cc50_solaris_sparc_fillUnoException( void*, const char*, uno_Any*, uno_Mapping * pCpp2Uno ); + +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx new file mode 100644 index 000000000000..df04a7ccb7dd --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/cpp2uno.cxx @@ -0,0 +1,696 @@ +/************************************************************************* + * + * $RCSfile: cpp2uno.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#define LEAK_STATIC_DATA +// #define TRACE(x) OSL_TRACE(x) +#define TRACE(x) + +#include <alloca.h> +#include <stl/list> +#include <stl/map> + +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif +#ifndef _OSL_MUTEX_HXX_ +#include <osl/mutex.hxx> +#endif + +#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ +#include <typelib/typedescription.hxx> +#endif +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ +#include <bridges/cpp_uno/type_misc.hxx> +#endif + +#include "cc50_solaris_sparc.hxx" + +using namespace com::sun::star::uno; +using namespace std; +using namespace osl; +using namespace rtl; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +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: [return ptr], this, params + char * pCppStack = (char *)pCallStack; + + // 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 = *pCallStack; + pCppStack += sizeof( void* ); + pUnoReturn = (cppu_relatesToInterface( pReturnTypeDescr ) + ? alloca( pReturnTypeDescr->nSize ) + : pCppReturn); // direct way + } + } + // pop this + pCppStack += sizeof( void* ); + + // stack space + OSL_ENSHURE( 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 ] = pUnoArgs[ nPos ] = + adjustPointer( pCppStack, pParamTypeDescr ); + 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 no 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 ); + + cc50_solaris_sparc_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_ENSHURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); + + // pCallStack: this, params + // _this_ ptr is patched cppu_Interface object + cppu_cppInterfaceProxy * pCppI = NULL; + if( nVtableCall & 0x80000000 ) + { + nVtableCall &= 0x7fffffff; + pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*(pCallStack +1); + } + else + pCppI = (cppu_cppInterfaceProxy *)(XInterface *)*pCallStack; + + typelib_InterfaceTypeDescription * pTypeDescr = pCppI->pTypeDescr; + +// OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, +// "### illegal vtable index!" ); +// if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) +// { +// RuntimeException aExc; +// aExc.Message = OUString::createFromAscii("illegal vtable index!"); +// aExc.Context = (XInterface *)pCppI; +// throw aExc; +// } + + // determine called method + OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; + OSL_ENSHURE( 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) + { + // standard XInterface vtable calls + 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[2] )->getTypeLibType() ); + OSL_ASSERT( 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[0] ), + &pInterface, pTD, cpp_acquire ); + pInterface->release(); + TYPELIB_DANGER_RELEASE( pTD ); + *(void **)pRegisterReturn = pCallStack[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, + pCallStack, pRegisterReturn ); + } + break; + } +// default: +// { +// RuntimeException aExc; +// aExc.Message = OUString::createFromAscii("no member description found!"); +// aExc.Context = (XInterface *)pCppI; +// throw aExc; +// // is here for dummy +// eRet = typelib_TypeClass_VOID; +// } + } + + return eRet; +} + + +//================================================================================================== +class MediateClassData +{ +public: + struct ClassDataBuffer + { + void** m_pVTable; + + ~ClassDataBuffer(); + }; +private: + + map< OUString, ClassDataBuffer* > m_aClassData; + Mutex m_aMutex; + + void createVTable( ClassDataBuffer*, typelib_InterfaceTypeDescription* ); +public: + const ClassDataBuffer* getClassData( typelib_InterfaceTypeDescription* ); + + MediateClassData() {} + ~MediateClassData(); +}; +//__________________________________________________________________________________________________ + +MediateClassData::ClassDataBuffer::~ClassDataBuffer() +{ + delete m_pVTable; +} + +//__________________________________________________________________________________________________ +MediateClassData::~MediateClassData() +{ + TRACE( "> calling ~MediateClassData(): freeing mediate vtables... <\n" ); + + // this MUST be the absolute last one which is called! + for ( map< OUString, ClassDataBuffer* >::iterator iPos( m_aClassData.begin() ); iPos != m_aClassData.end(); ++iPos ) + { + // todo +// delete (*iPos).second; + } +} + +//__________________________________________________________________________________________________ + +const MediateClassData::ClassDataBuffer* MediateClassData::getClassData( typelib_InterfaceTypeDescription* pType ) +{ + MutexGuard aGuard( m_aMutex ); + + map< OUString, ClassDataBuffer* >::iterator element = m_aClassData.find( pType->aBase.pTypeName ); + if( element != m_aClassData.end() ) + return (*element).second; + + ClassDataBuffer* pBuffer = new ClassDataBuffer(); + createVTable( pBuffer, pType ); + m_aClassData[ pType->aBase.pTypeName ] = pBuffer; + return pBuffer; +} + +//================================================================================================== +void cpp_vtable_call( int nTableEntry, void** pCallStack ) +{ + long nRegReturn[2]; + typelib_TypeClass aType = + cpp_mediate( nTableEntry, pCallStack+17, (sal_Int64*)nRegReturn ); + switch( aType ) + { + // move return value into register space + // (will be loaded by machine code snippet) + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + pCallStack[ 17 ] = (void*)(((char*)nRegReturn)[0]); + break; + case typelib_TypeClass_CHAR: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + pCallStack[ 17 ] = (void*)(((short*)nRegReturn)[0]); + break; + case typelib_TypeClass_DOUBLE: + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + // move long to %i1 + pCallStack[ 18 ] = (void*) nRegReturn[ 1 ]; + case typelib_TypeClass_FLOAT: + default: + // move long to %i0 + pCallStack[ 17 ] = (void*) nRegReturn[ 0 ]; + break; + } +} + +enum SpecialReturnType { None, ReturnFloat, ReturnDouble }; + +//__________________________________________________________________________________________________ +void MediateClassData::createVTable( ClassDataBuffer* pBuffer, typelib_InterfaceTypeDescription* pType ) +{ + // get all member functions + list< SpecialReturnType > aSpecialReturn; + list< sal_Bool > aComplexReturn; + + for( int n = 0; n < pType->nAllMembers; n++ ) + { + typelib_TypeDescription* pMember = NULL; + TYPELIB_DANGER_GET( &pMember, pType->ppAllMembers[n] ); + if( pMember->eTypeClass == typelib_TypeClass_INTERFACE_ATTRIBUTE ) + { + typelib_TypeDescription * pRetTD = 0; + TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceAttributeTypeDescription *)pMember)->pAttributeTypeRef ); + // get method + switch( pRetTD->eTypeClass ) + { + case typelib_TypeClass_FLOAT: + aSpecialReturn.push_back( ReturnFloat ); + break; + case typelib_TypeClass_DOUBLE: + aSpecialReturn.push_back( ReturnDouble ); + break; + default: + aSpecialReturn.push_back( None ); + break; + } + aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); + // set method + if( ! ((typelib_InterfaceAttributeTypeDescription*)pMember)->bReadOnly ) + { + aSpecialReturn.push_back( None ); + aComplexReturn.push_back( sal_False ); + } + TYPELIB_DANGER_RELEASE( pRetTD ); + } + else + { + typelib_TypeDescription * pRetTD = 0; + TYPELIB_DANGER_GET( &pRetTD, ((typelib_InterfaceMethodTypeDescription *)pMember)->pReturnTypeRef ); + switch( pRetTD->eTypeClass ) + { + case typelib_TypeClass_FLOAT: + aSpecialReturn.push_back( ReturnFloat ); + break; + case typelib_TypeClass_DOUBLE: + aSpecialReturn.push_back( ReturnDouble ); + break; + default: + aSpecialReturn.push_back( None ); + break; + } + aComplexReturn.push_back( !cppu_isSimpleType( pRetTD ) ); + TYPELIB_DANGER_RELEASE( pRetTD ); + } + TYPELIB_DANGER_RELEASE( pMember ); + } + + const int nSnippetSize = 256; + int nSize = aSpecialReturn.size(); + char * pSpace = (char *)rtl_allocateMemory( ((nSize+3)*sizeof(void *)) + (nSize * nSnippetSize) ); + pBuffer->m_pVTable = (void**)pSpace; + + char * pCode = pSpace + ((nSize+3)*sizeof(void *)); + void ** pvft = (void **)pSpace; + pvft[0] = NULL; // RTTI + pvft[1] = NULL; // null + pvft[2] = NULL; // destructor + + // setup vft and code + for ( sal_Int32 nPos = 0; nPos < nSize; ++nPos ) + { + unsigned long * codeSnip = + (unsigned long*)((unsigned char *)pCode + (nPos*nSnippetSize)); + SpecialReturnType eRet = aSpecialReturn.front(); + aSpecialReturn.pop_front(); + unsigned long nTablePos = nPos; + if( aComplexReturn.front() ) + nTablePos |= 0x80000000; + aComplexReturn.pop_front(); + pvft[nPos+3] = codeSnip; + /*generate this code: + * save %sp, -104, %sp + * st %i0, [ %fp + 68 ] + * st %i1, [ %fp + 72 ] + * st %i2, [ %fp + 76 ] + * st %i3, [ %fp + 80 ] + * st %i4, [ %fp + 84 ] + * st %i5, [ %fp + 88 ] + * prepare vtable entry + * sethi %hi( nTablePos ), %o0 + * or %lo( nTablePos ), %o0 + * + * ( if complex return, set high bit ) + * + * mov %fp, %o1 prepare stack + * call cpp_vtable_call + * nop + * ld [ %fp + 68 ], %i0 restore (perhaps changed) registers + * ld [ %fp + 72 ], %i1 + * ld [ %fp + 76 ], %i2 + * ld [ %fp + 80 ], %i3 + * ld [ %fp + 84 ], %i4 + * ld [ %fp + 88 ], %i5 + * + * ( if double return value, get (%i0, %i1) into %f0 + * std %i0, [ %fp - 8 ] + * ldd [ %fp - 8 ], %f0 + * + * ( if float return value, get (%i0) into %f0 + * ld [ %fp + 68 ], %f0 + * + * jmp %i7+8 return + * restore + *exception cleanup code + * call __Crun::ex_rethrow_q + * nop + */ + *codeSnip++ = 0x9de3bf98; + *codeSnip++ = 0xf027a044; + *codeSnip++ = 0xf227a048; + *codeSnip++ = 0xf427a04c; + *codeSnip++ = 0xf627a050; + *codeSnip++ = 0xf827a054; + *codeSnip++ = 0xfa27a058; + *codeSnip++ = 0x11000000 | (nTablePos >> 10); + *codeSnip++ = 0x90122000 | (nTablePos & 1023); + *codeSnip++ = 0x9210001e; + unsigned long rel32 = (unsigned long)cpp_vtable_call - ((unsigned long)codeSnip); + *codeSnip++ = 0x40000000 | (rel32 >> 2 ); + *codeSnip++ = 0x01000000; + *codeSnip++ = 0xf007a044; + *codeSnip++ = 0xf207a048; + *codeSnip++ = 0xf407a04c; + *codeSnip++ = 0xf607a050; + *codeSnip++ = 0xf807a054; + *codeSnip++ = 0xfa07a058; + + switch( eRet ) + { + case ReturnFloat: + *codeSnip++ = 0xc107a044; + break; + case ReturnDouble: + *codeSnip++ = 0xf03fbff8; + *codeSnip++ = 0xc11fbff8; + break; + default: + break; + } + + unsigned long* exc_frame = codeSnip; + *codeSnip++ = 0x81c7e008; + *codeSnip++ = 0x81e80000; + unsigned long* exc_handler = codeSnip; + *codeSnip++ = 0x40000000 | (((unsigned long)__Crun::ex_rethrow_q) >> 2); + *codeSnip++ = 0x01000000; + + unsigned long* frame_info = new unsigned long[5]; + memset( frame_info, 0, 5*sizeof(unsigned long) ); + frame_info[ 0 ] = (unsigned long)exc_frame; + frame_info[ 2 ] = (unsigned long)(exc_handler); + _ex_register( frame_info, 1 ); + } +} + +//================================================================================================== +void SAL_CALL cppu_cppInterfaceProxy_patchVtable( + XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + 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 + } + } + *(const void **)pCppI = s_pMediateClassData->getClassData( pTypeDescr )->m_pVTable + 1; +} + +} + +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) +{ + CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( pCppEnv ); +} +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_ext_getMapping( + uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) +{ + CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( ppMapping, pFrom, pTo ); +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx new file mode 100644 index 000000000000..0c0b2eda5dad --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/except.cxx @@ -0,0 +1,421 @@ +/************************************************************************* + * + * $RCSfile: except.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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 <dlfcn.h> +#include <new.h> +#include <typeinfo> +#include <stl/list> +#include <stl/map> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ +#include <typelib/typedescription.hxx> +#endif +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#include "cc50_solaris_sparc.hxx" + +// need a += operator for OString and sal_Char +namespace rtl +{ + inline OString& operator+=( OString& rString, sal_Char cAdd ) + { + sal_Char add[2]; + add[0] = cAdd; + add[1] = 0; + return rString += add; + } +} + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +static OString toUNOname( const OString & rRTTIname ) +{ + OString aRet; + + const sal_Char* pRTTI = rRTTIname.getStr(); + const sal_Char* pOrg = pRTTI; + const sal_Char* pLast = pRTTI; + + while( 1 ) + { + if( *pRTTI == ':' || ! *pRTTI ) + { + if( aRet.getLength() ) + aRet += "."; + aRet += rRTTIname.copy( pLast - pOrg, pRTTI - pLast ); + while( *pRTTI == ':' ) + pRTTI++; + pLast = pRTTI; + if( ! *pRTTI ) + break; + } + else + pRTTI++; + } + + return aRet; +} +//================================================================================================== +static OString toRTTIname( const OString & rUNOname ) +{ + OString aRet; + + int nTokens = rUNOname.getTokenCount( '.' ); + for( int i = 0; i < nTokens; i++ ) + { + if( i > 0 ) + aRet += "::"; + aRet += rUNOname.getToken( i, '.' ); + } + + return aRet; +} +//================================================================================================== + +static int replaceQdDdD( const OString& rIn, OString& rOutdD, OString& rOutdDdD ) +{ + int nRet = 0; + int nLen = rIn.getLength(), i, n; + rOutdD = OString(); + rOutdDdD = OString(); + for( i = 0, n = 0; ( i = rIn.indexOf( 'Q', i ) ) != -1 && i < nLen; i++ ) + { + rOutdD += rIn.copy( n, i-n+1 ); + rOutdDdD += rIn.copy( n, i-n+1 ); + n = i+1; + rOutdD += "dD"; + rOutdDdD += "dDdD"; + nRet++; + } + rOutdD += rIn.copy( n ); + rOutdDdD += rIn.copy( n ); + return nRet; +} + +static OString toRTTIsymbolname( const OString & rRTTIname ) +{ + if( ! rRTTIname.getLength() ) + return OString(); + + OString aRet; + OString aPrefix; + + int nUnoTokens = rRTTIname.getTokenCount( ':' ); + int nAdjust = 0; + for( int i = 0; i < nUnoTokens; i++ ) + { + OString aToken( rRTTIname.getToken( i, ':' ) ); + int nBytes = aToken.getLength(); + if( nBytes ) + { + OString aAdd; + if( nBytes > 25 ) + { + aAdd += (sal_Char)( nBytes/26 + 'a' ); + aAdd += (sal_Char)( nBytes % 26 + 'A' ); + } + else + aAdd += (sal_Char)( nBytes + 'A' ); + aRet += aAdd; + // special case "Q" + if( ( ( nBytes % 26 ) +'A' ) == 'Q' ) + { + aRet += "dD"; + nAdjust += 2; + } + + OString adD, adDdD; + int nRepl = replaceQdDdD( aToken, adD, adDdD ); + if( nUnoTokens == 1 ) + { + // must replace "Q" by "QdD" + aRet += adD; + nAdjust += 2* nRepl; + } + else + { + // must replace "Q" by "QdDdD" + aRet += adDdD; + nAdjust += 4* nRepl; + } + + if( i < nUnoTokens - 1 ) + { + aPrefix += aAdd; + // must replace "Q" by "QdD" + aPrefix += adD; + } + } + } + aRet += '_'; + + if( aPrefix.getLength() ) + { + int nBytes = aRet.getLength() - nAdjust + 10; + if( nBytes > 25 ) + { + aPrefix += (sal_Char)( nBytes/26 + 'a' ); + aPrefix += (sal_Char)( nBytes % 26 + 'A' ); + } + else + aPrefix += (sal_Char)( nBytes + 'A' ); + + + aRet = "__1c" + aPrefix + "__RTTI__1n" + aRet + "_"; + } + else + aRet = "__RTTI__1n"+aRet; + + return aRet; +} + + +//################################################################################################## +//#### RTTI simulation ############################################################################# +//################################################################################################## + +class RTTIHolder +{ + static std::map< OString, void* > aAllRTTI; +public: + static void* getRTTI( const OString& rTypename ); + static void* getRTTI_UnoName( const OString& rUnoTypename ) + { return getRTTI( toRTTIname( rUnoTypename ) ); } + + static void* insertRTTI( const OString& rTypename ); + static void* insertRTTI_UnoName( const OString& rTypename ) + { return insertRTTI( toRTTIname( rTypename ) ); } +}; + +std::map< OString, void* > RTTIHolder::aAllRTTI; + +#ifdef DEBUG +#include <stdio.h> +#endif + +void* RTTIHolder::getRTTI( const OString& rTypename ) +{ + std::map< OString, void* >::iterator element; + + element = aAllRTTI.find( rTypename ); + if( element != aAllRTTI.end() ) + return (*element).second; + // get rtti + // look for existing type info + static void* pMain = dlopen( NULL, RTLD_NOW | RTLD_GLOBAL ); + + void* pSymbol = dlsym( pMain, toRTTIsymbolname( rTypename ).getStr() ); + + if( pSymbol ) + { + // there exists type info, use it (otherwise it will not be equal + // since addresses - not contents - are matched in RTTI compare) + aAllRTTI[ rTypename ] = pSymbol; + return pSymbol; + } + +#ifdef DEBUG + fprintf( stderr, "exception type \"%s\" not found via dlsym !!!\n", toRTTIsymbolname( rTypename ).getStr() ); +#endif + + // no type found (time for plan b: look for base type ) + return NULL; +} + +static long nMagicId = 1; + +void* RTTIHolder::insertRTTI( const OString& rTypename ) +{ +#ifdef DEBUG + fprintf( stderr, "generating base RTTI for type %s\n", rTypename.getStr() ); +#endif + void** pRTTI = new void*[ 19 ]; + memset( pRTTI, 0, 19*sizeof( void* ) ); + pRTTI[ 0 ] = (void*)strdup( rTypename.getStr() ); + pRTTI[ 2 ] = (void*)(7*sizeof(void*)); + pRTTI[ 3 ] = (void*)nMagicId++; + pRTTI[ 4 ] = (void*)nMagicId++; + pRTTI[ 5 ] = (void*)nMagicId++; + pRTTI[ 6 ] = (void*)nMagicId++; + + pRTTI[ 9 ] = pRTTI[ 3 ]; + pRTTI[ 10 ] = pRTTI[ 4 ]; + pRTTI[ 11 ] = pRTTI[ 5 ]; + pRTTI[ 12 ] = pRTTI[ 6 ]; + pRTTI[ 13 ] = (void*)0x80000000; + + aAllRTTI[ rTypename ] = (void*)pRTTI; + return pRTTI; +} + +//-------------------------------------------------------------------------------------------------- + +static void* generateRTTI( typelib_CompoundTypeDescription * pCompTypeDescr ) +{ + static ::osl::Mutex aMutex; + ::osl::Guard< ::osl::Mutex > guard( aMutex ); + + OString aCompTypeName( OUStringToOString( pCompTypeDescr->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US ) ); + + void* pRTTI = RTTIHolder::getRTTI_UnoName( aCompTypeName ); + if( pRTTI ) + return pRTTI; + + // uh oh. Compiler did not generate RTTI for this type + // but that means that this was neither thrown nor caught explicitly + // then let's downcast it until we find real RTTI + // since the object will be destructed by deleteException which does + // this with the correct type description all should be well + + if( ! pCompTypeDescr->pBaseTypeDescription ) + // this is a base type (and a bad case, we should not need to generate any RTTI) + return RTTIHolder::insertRTTI_UnoName( aCompTypeName ); + + // get base class RTTI + void* pSuperRTTI = generateRTTI( pCompTypeDescr->pBaseTypeDescription ); + OSL_ENSHURE( pSuperRTTI, "could not generate RTTI for supertype!" ); + + return pSuperRTTI; +} + +//-------------------------------------------------------------------------------------------------- + +static void deleteException( void* pExc ) +{ + typelib_TypeDescription* pType = (typelib_TypeDescription*)((void**)pExc)[-2]; + uno_destructData( pExc, pType, cpp_release ); + typelib_typedescription_release( pType ); +} + +//__________________________________________________________________________________________________ + +//################################################################################################## +//#### exported #################################################################################### +//################################################################################################## + +void cc50_solaris_sparc_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +{ + typelib_TypeDescription * pTypeDescr = 0; + // will be released by deleteException + typelib_typedescriptionreference_getDescription( &pTypeDescr, pUnoExc->pType ); + + void* pRTTI = generateRTTI( (typelib_CompoundTypeDescription *)pTypeDescr ); + + // a must be + OSL_ENSHURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" ); + + void** pExcSpace = (void**)__Crun::ex_alloc( pTypeDescr->nSize + 8 ); + void * pCppExc = (void*)(((char*)pExcSpace)+8); + // will be released in generated dtor + // alignment to 8 + pExcSpace[0] = pTypeDescr; + uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); + + // destruct uno exception + uno_any_destruct( pUnoExc, 0 ); + + __Crun::ex_throw( pCppExc, (const __Crun::static_type_info*)pRTTI, deleteException ); +} + +void cc50_solaris_sparc_fillUnoException( + void* pCppExc, + const char* pInfo, + uno_Any* pExc, + uno_Mapping * pCpp2Uno ) +{ + OUString aName( OStringToOUString( toUNOname( pInfo ), RTL_TEXTENCODING_ASCII_US ) ); + typelib_TypeDescription * pExcTypeDescr = 0; + typelib_typedescription_getByName( + &pExcTypeDescr, + aName.pData ); + if (pExcTypeDescr) + { + // 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 ); + } +} + +} + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk new file mode 100644 index 000000000000..39d3be889633 --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/makefile.mk @@ -0,0 +1,111 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ +# +# 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=cppu +TARGET=sunpro5_uno +LIBTARGET=no +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- + +.IF "$(COM)$(CPU)" == "C50S" + +#CFLAGS += -O5 -xO5 + +SLOFILES= \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj \ + $(SLO)$/except.obj \ + $(SLO)$/call.obj + +SHL1TARGET= $(TARGET) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB= i$(TARGET) + +SHL1OBJS= \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj \ + $(SLO)$/except.obj \ + $(SLO)$/call.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) + +.ENDIF + +.INCLUDE : target.mk + + +$(SLO)$/call.obj: call.s + as -o $(SLO)$/call.o call.s ; touch $(SLO)$/call.obj + diff --git a/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx new file mode 100644 index 000000000000..d903c1ad23bb --- /dev/null +++ b/bridges/source/cpp_uno/cc50_solaris_sparc/uno2cpp.cxx @@ -0,0 +1,423 @@ +/************************************************************************* + * + * $RCSfile: uno2cpp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:48 $ + * + * 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 <alloca.h> +#include <stl/map> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif + +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ +#include <bridges/cpp_uno/type_misc.hxx> +#endif + +#include "cc50_solaris_sparc.hxx" + +using namespace std; +using namespace osl; +using namespace rtl; +using namespace com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +extern "C" { + void callVirtualMethod( + void * pThis, + sal_Int32 nVtableIndex, + void * pRegisterReturn, + typelib_TypeClass eReturnType, + sal_Int32 * pStackLongs, + sal_Int32 nStackLongs + ); + extern void* callVirtualMethodExceptionHandler; +} + +//================================================================================================== +static void cpp_call( + cppu_unoInterfaceProxy * pThis, + sal_Int32 nVtableCall, + typelib_TypeDescriptionReference * pReturnTypeRef, + sal_Int32 nParams, typelib_MethodParameter * pParams, + sal_Int32 nExceptions, typelib_TypeDescriptionReference ** ppExceptionRefs, + void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) +{ + // pCppI is cc50_solaris_sparc this pointer + OSL_ENSHURE( pThis, "### no interface given!" ); + + // max space for: [complex ret ptr], values|ptr ... + char * pCppStack = (char *)alloca( ((nParams+3) * sizeof(sal_Int64)) ); + char * pCppStackStart = pCppStack; + + // return + typelib_TypeDescription * pReturnTypeDescr = 0; + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + OSL_ENSHURE( 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* ); + + // 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 )) + { + pCppArgs[ nPos ] = adjustPointer( pCppStack, pParamTypeDescr ); + uno_copyAndConvertData( pCppArgs[nPos], 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 + } + +// seems that EH registration for callVirtualMethod is not really +// necessary + +// static unsigned long* pFrameInfo = NULL; + +// if( ! pFrameInfo ) +// { +// pFrameInfo = new unsigned long[ 7 ]; +// pFrameInfo[ 0 ] = 0x40000000 | (((unsigned long)__Crun::ex_rethrow_q) >> 2); +// pFrameInfo[ 1 ] = 0x01000000; +// pFrameInfo[ 2 ] = (unsigned long)callVirtualMethodExceptionHandler; +// pFrameInfo[ 3 ] = 0; +// pFrameInfo[ 4 ] = (unsigned long)pFrameInfo - (unsigned long)callVirtualMethodExceptionHandler; +// pFrameInfo[ 5 ] = 0; +// pFrameInfo[ 6 ] = 0; +// _ex_register( pFrameInfo+2, 1 ); +// } + + try + { + int nStackLongs = (pCppStack - pCppStackStart)/sizeof(sal_Int32); + if( nStackLongs & 1 ) + // stack has to be 8 byte aligned + nStackLongs++; + + callVirtualMethod( + pThis->pCppI, + nVtableCall, + pCppReturn, + pReturnTypeDescr->eTypeClass, + (sal_Int32 *)pCppStackStart, + nStackLongs + ); + + // 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( ... ) + { + // get exception + cc50_solaris_sparc_fillUnoException( __Crun::ex_get(), + __Cimpl::ex_name(), + *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 ) +{ + // 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_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); + + sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos]; + OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + + typelib_TypeDescriptionReference * pRuntimeExcRef = 0; + + if (pReturn) + { + // dependent dispatch + cpp_call( pThis, nVtableCall, + ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, + 0, 0, // no params + 1, &pRuntimeExcRef, // RuntimeException + 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, + 1, &pRuntimeExcRef, + 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_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); + + sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos]; + OSL_ENSHURE( 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() ); + OSL_ASSERT( 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, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nExceptions, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->ppExceptions, + pReturn, pArgs, ppException ); + } + break; + } + default: + { + ::com::sun::star::uno::RuntimeException aExc; + aExc.Message = OUString::createFromAscii("illegal member type description!"); + aExc.Context = pThis->pCppI; + + typelib_TypeDescription * pTD = 0; + const Type & rExcType = ::getCppuType( (const ::com::sun::star::uno::RuntimeException *)0 ); + TYPELIB_DANGER_GET( &pTD, rExcType.getTypeLibType() ); + uno_any_construct( *ppException, &aExc, pTD, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + } + } +} + +} + diff --git a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx new file mode 100644 index 000000000000..8b7ddf39098b --- /dev/null +++ b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx @@ -0,0 +1,563 @@ +/************************************************************************* + * + * $RCSfile: cpp2uno.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#define LEAK_STATIC_DATA +// #define TRACE(x) OSL_TRACE(x) +#define TRACE(x) + +#pragma warning( disable : 4237 ) +#include <stl/list> +#include <malloc.h> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif + +#ifndef _TYPELIB_TYPEDESCRIPTION_HXX_ +#include <typelib/typedescription.hxx> +#endif +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ +#include <bridges/cpp_uno/type_misc.hxx> +#endif + +#include "msci.hxx" + +using namespace std; +using namespace rtl; +using namespace osl; +using namespace com::sun::star::uno; + + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +static inline 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, this, [complex return ptr], params + char * pCppStack = (char *)(pCallStack +2); + + // 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 + } + } + + // stack space + OSL_ENSHURE( 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 + while (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 ); + + msci_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 + while (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 __cdecl cpp_mediate( + void ** pCallStack, sal_Int32 nVtableCall, + sal_Int64 * pRegisterReturn /* space for register return */ ) +{ + OSL_ENSHURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" ); + + // pCallStack: ret adr, this, [ret *], params + // _this_ ptr is patched cppu_XInterfaceProxy object + cppu_cppInterfaceProxy * pThis = static_cast< cppu_cppInterfaceProxy * >( + reinterpret_cast< XInterface * >( pCallStack[1] ) ); + + typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr; + OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, + "### illegal vtable index!" ); + if (nVtableCall >= pTypeDescr->nMapFunctionIndexToMemberIndex) + { + throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal vtable index!") ), + (XInterface *)pThis ); + } + + // determine called method + sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nVtableCall]; + OSL_ENSHURE( 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( + pThis, 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( + pThis, aMemberDescr.get(), + 0, // indicates void return + 1, &aParam, + pCallStack, pRegisterReturn ); + } + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + // is METHOD + switch (nVtableCall) + { + // standard XInterface vtable calls + case 1: // acquire() + pThis->acquireProxy(); // non virtual call! + eRet = typelib_TypeClass_VOID; + break; + case 2: // release() + pThis->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() ); + OSL_ASSERT( pTD ); + + XInterface * pInterface = 0; + (*pThis->pBridge->pCppEnv->getRegisteredInterface)( + pThis->pBridge->pCppEnv, + (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD ); + + if (pInterface) + { + uno_any_construct( reinterpret_cast< uno_Any * >( pCallStack[2] ), + &pInterface, pTD, cpp_acquire ); + pInterface->release(); + TYPELIB_DANGER_RELEASE( pTD ); + *(void **)pRegisterReturn = pCallStack[2]; + eRet = typelib_TypeClass_ANY; + break; + } + TYPELIB_DANGER_RELEASE( pTD ); + } // else perform queryInterface() + default: + eRet = cpp2uno_call( + pThis, aMemberDescr.get(), + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams, + ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams, + pCallStack, pRegisterReturn ); + } + break; + } + default: + { + throw RuntimeException( + OUString( RTL_CONSTASCII_USTRINGPARAM("no member description found!") ), + (XInterface *)pThis ); + // is here for dummy + eRet = typelib_TypeClass_VOID; + } + } + + return eRet; +} + +//================================================================================================== +class MediateVtables +{ + //---------------------------------------------------------------------------------------------- + struct DefaultRTTIEntry + { + sal_Int32 _n0, _n1, _n2; + type_info * _pRTTI; + + DefaultRTTIEntry() + : _n0( 0 ) + , _n1( 0 ) + , _n2( 0 ) + { _pRTTI = msci_getRTTI( "com.sun.star.uno.XInterface" ); } + }; + + typedef list<void * > t_pSpacesList; + + Mutex _aMutex; + t_pSpacesList _aSpaces; + + sal_Int32 _nCurrent; + const void * _pCurrent; + +public: + const void * getMediateVtable( sal_Int32 nSize ); + + MediateVtables( sal_Int32 nSize = 256 ) + : _nCurrent( 0 ) + , _pCurrent( 0 ) + { getMediateVtable( nSize ); } + ~MediateVtables(); +}; +//__________________________________________________________________________________________________ +MediateVtables::~MediateVtables() +{ + TRACE( "> calling ~MediateVtables(): freeing mediate vtables... <\n" ); + + MutexGuard aGuard( _aMutex ); + + // this MUST be the absolute last one which is called! + for ( t_pSpacesList::iterator iPos( _aSpaces.begin() ); iPos != _aSpaces.end(); ++iPos ) + { + rtl_freeMemory( *iPos ); + } +} + +//================================================================================================== +/** + * is called on incoming vtable calls + * (called by asm snippets) + */ +static __declspec(naked) void __cdecl cpp_vtable_call(void) +{ +__asm + { + sub esp, 8 // space for immediate return type + push esp + push eax // vtable index + mov eax, esp + add eax, 16 + push eax // original stack ptr + + call cpp_mediate + add esp, 12 + + cmp eax, typelib_TypeClass_FLOAT + je Lfloat + cmp eax, typelib_TypeClass_DOUBLE + je Ldouble + cmp eax, typelib_TypeClass_HYPER + je Lhyper + cmp eax, typelib_TypeClass_UNSIGNED_HYPER + je Lhyper + // rest is eax + pop eax + add esp, 4 + ret +Lhyper: + pop eax + pop edx + ret +Lfloat: + fld dword ptr [esp] + add esp, 8 + ret +Ldouble: + fld qword ptr [esp] + add esp, 8 + ret + } +} + +//__________________________________________________________________________________________________ +const void * MediateVtables::getMediateVtable( sal_Int32 nSize ) +{ + if (_nCurrent < nSize) + { + TRACE( "> need larger vtable! <\n" ); + + // dont ever guard each time, so ask twice when guarded + MutexGuard aGuard( _aMutex ); + if (_nCurrent < nSize) + { + nSize = (nSize +1) & 0xfffffffe; + char * pSpace = (char *)rtl_allocateMemory( ((1+nSize)*sizeof(void *)) + (nSize*12) ); + _aSpaces.push_back( pSpace ); + + // on index -1 write default rtti entry + static DefaultRTTIEntry s_defaultInterfaceRTTI; + *(void **)pSpace = &s_defaultInterfaceRTTI; + + void ** pvft = (void **)(pSpace + sizeof(void *)); + char * pCode = pSpace + ((1+nSize)*sizeof(void *)); + + // setup vft and code + for ( sal_Int32 nPos = 0; nPos < nSize; ++nPos ) + { + unsigned char * codeSnip = (unsigned char *)pCode + (nPos *12); + pvft[nPos] = codeSnip; + + /** + * vtable calls detonate on these code snippets + */ + // mov eax, nPos + *codeSnip++ = 0xb8; + *(sal_Int32 *)codeSnip = nPos; + codeSnip += sizeof(sal_Int32); + // jmp rel32 cpp_vtable_call + *codeSnip++ = 0xe9; + *(sal_Int32 *)codeSnip = ((unsigned char *)cpp_vtable_call) - codeSnip - sizeof(sal_Int32); + } + _pCurrent = pSpace + sizeof(void *); + _nCurrent = nSize; + } + } + return _pCurrent; +} + +//================================================================================================== +void SAL_CALL cppu_cppInterfaceProxy_patchVtable( + XInterface * pCppI, typelib_InterfaceTypeDescription * pTypeDescr ) +{ + static MediateVtables * s_pMediateVtables = 0; + if (! s_pMediateVtables) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pMediateVtables) + { +#ifdef LEAK_STATIC_DATA + s_pMediateVtables = new MediateVtables(); +#else + static MediateVtables s_aMediateVtables; + s_pMediateVtables = &s_aMediateVtables; +#endif + } + } + *(const void **)pCppI = s_pMediateVtables->getMediateVtable( + pTypeDescr->nMapFunctionIndexToMemberIndex ); +} + +} + +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_initEnvironment( uno_Environment * pCppEnv ) +{ + CPPU_CURRENT_NAMESPACE::cppu_cppenv_initEnvironment( pCppEnv ); +} +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_ext_getMapping( + uno_Mapping ** ppMapping, uno_Environment * pFrom, uno_Environment * pTo ) +{ + CPPU_CURRENT_NAMESPACE::cppu_ext_getMapping( ppMapping, pFrom, pTo ); +} + diff --git a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx new file mode 100644 index 000000000000..9bab2d6bd5d5 --- /dev/null +++ b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx @@ -0,0 +1,538 @@ +/************************************************************************* + * + * $RCSfile: except.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#define LEAK_STATIC_DATA +#define TRACE(x) OSL_TRACE(x) +// #define TRACE(x) + +#pragma warning( disable : 4237 ) +#include <stl/hash_map> +#include <sal/config.h> +#include <malloc.h> +#include <new.h> +#include <typeinfo.h> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif + +#ifndef _RTL_STRBUF_HXX_ +#include <rtl/strbuf.hxx> +#endif + +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _COM_SUN_STAR_UNO_ANY_HXX_ +#include <com/sun/star/uno/Any.hxx> +#endif + +#include "msci.hxx" + +#pragma pack(push, 8) + +using namespace com::sun::star::uno; +using namespace std; +using namespace osl; +using namespace rtl; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +static inline OString toUNOname( const OString & rRTTIname ) +{ + OStringBuffer aRet( 64 ); + OString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@ + for ( sal_Int32 nToken = aStr.getTokenCount( '@' ); nToken--; ) + { + aRet.append( aStr.getToken( nToken, '@' ) ); + if (nToken) + aRet.append( '.' ); + } + return aRet.makeStringAndClear(); +} +//================================================================================================== +static inline OString toRTTIname( const OString & rUNOname ) +{ + OStringBuffer aRet( 64 ); + aRet.append( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU" + for ( sal_Int32 nToken = rUNOname.getTokenCount( '.' ); nToken--; ) + { + aRet.append( rUNOname.getToken( nToken, '.' ) ); + aRet.append( '@' ); + } + aRet.append( '@' ); + return aRet.makeStringAndClear(); +} + + +//################################################################################################## +//#### RTTI simulation ############################################################################# +//################################################################################################## + + +//================================================================================================== +struct FctOStringHash : public unary_function< const OString &, size_t > +{ + size_t operator()( const OString & rStr ) const + { return rStr.hashCode(); } +}; +typedef hash_map< OString, void *, FctOStringHash, equal_to< OString > > t_string2PtrMap; + +//================================================================================================== +class RTTInfos +{ + Mutex _aMutex; + t_string2PtrMap _allRTTI; + + static OString toRawName( const OString & rUNOname ); +public: + type_info * getRTTI( const OString & rUNOname ); + + RTTInfos(); + ~RTTInfos(); +}; + +//================================================================================================== +class __type_info +{ + friend type_info * RTTInfos::getRTTI( const OString & ); + friend sal_Int32 msci_filterCppException( LPEXCEPTION_POINTERS, uno_Any *, uno_Mapping * ); + +public: + virtual ~__type_info(); + + __type_info( void * m_data, const char * m_d_name ) + : _m_data( m_data ) + { ::strcpy( _m_d_name, m_d_name ); } + +private: + void * _m_data; + char _m_d_name[1]; +}; +//__________________________________________________________________________________________________ +__type_info::~__type_info() +{ +} +//__________________________________________________________________________________________________ +type_info * RTTInfos::getRTTI( const OString & rUNOname ) +{ + // a must be + OSL_ENSHURE( sizeof(__type_info) == sizeof(type_info), "### type info structure size differ!" ); + + MutexGuard aGuard( _aMutex ); + const t_string2PtrMap::const_iterator iFind( _allRTTI.find( rUNOname ) ); + + // check if type is already available + if (iFind == _allRTTI.end()) + { + // insert new type_info + OString aRawName( toRTTIname( rUNOname ) ); + __type_info * pRTTI = new(rtl_allocateMemory( sizeof(__type_info) + aRawName.getLength() )) + __type_info( NULL, aRawName.getStr() ); + // put into map + _allRTTI[rUNOname] = pRTTI; + + return (type_info *)pRTTI; + } + else + { + return (type_info *)(*iFind).second; + } +} +//__________________________________________________________________________________________________ +RTTInfos::RTTInfos() +{ +} +//__________________________________________________________________________________________________ +RTTInfos::~RTTInfos() +{ + TRACE( "> freeing generated RTTI infos... <\n" ); + + MutexGuard aGuard( _aMutex ); + for ( t_string2PtrMap::const_iterator iPos( _allRTTI.begin() ); + iPos != _allRTTI.end(); ++iPos ) + { + __type_info * pType = (__type_info *)(*iPos).second; + pType->~__type_info(); // obsolete, but good style... + rtl_freeMemory( pType ); + } +} + + +//################################################################################################## +//#### Exception raising ########################################################################### +//################################################################################################## + + +//================================================================================================== +struct ObjectFunction +{ + char somecode[12]; + typelib_TypeDescription * _pTypeDescr; // type of object + + ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ); + ~ObjectFunction(); +}; +//__________________________________________________________________________________________________ +ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) + : _pTypeDescr( pTypeDescr ) +{ + typelib_typedescription_acquire( _pTypeDescr ); + + unsigned char * pCode = (unsigned char *)somecode; + // a must be! + OSL_ENSHURE( (void *)this == (void *)pCode, "### unexpected!" ); + + // push ObjectFunction this + *pCode++ = 0x68; + *(void **)pCode = this; + pCode += sizeof(void *); + // jmp rel32 fpFunc + *pCode++ = 0xe9; + *(sal_Int32 *)pCode = ((unsigned char *)fpFunc) - pCode - sizeof(sal_Int32); +} +//__________________________________________________________________________________________________ +ObjectFunction::~ObjectFunction() +{ + typelib_typedescription_release( _pTypeDescr ); +} + +//================================================================================================== +static void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis ) +{ + uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire ); + return pExcThis; +} +//================================================================================================== +static void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis ) +{ + uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release ); + return pExcThis; +} + +// these are non virtual object methods; there is no this ptr on stack => ecx supplies _this_ ptr + +//================================================================================================== +static __declspec(naked) copyConstruct() +{ + __asm + { + // ObjectFunction this already on stack + push [esp+8] // source exc object this + push ecx // exc object + call __copyConstruct + add esp, 12 // + ObjectFunction this + ret 4 + } +} +//================================================================================================== +static __declspec(naked) destruct() +{ + __asm + { + // ObjectFunction this already on stack + push ecx // exc object + call __destruct + add esp, 8 // + ObjectFunction this + ret + } +} + +//================================================================================================== +struct ExceptionType +{ + sal_Int32 _n0; + type_info * _pTypeInfo; + sal_Int32 _n1, _n2, _n3, _n4; + ObjectFunction * _pCopyCtor; + sal_Int32 _n5; + + ExceptionType( typelib_TypeDescription * pTypeDescr ) + : _n0( 0 ) + , _n1( 0 ) + , _n2( -1 ) + , _n3( 0 ) + , _n4( pTypeDescr->nSize ) + , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) ) + , _n5( 0 ) + { _pTypeInfo = msci_getRTTI( OUStringToOString( pTypeDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) ); } + ~ExceptionType() + { delete _pCopyCtor; } +}; +//================================================================================================== +struct RaiseInfo +{ + sal_Int32 _n0; + ObjectFunction * _pDtor; + sal_Int32 _n2; + void * _types; + sal_Int32 _n3, _n4; + + RaiseInfo( typelib_TypeDescription * pTypeDescr ); + ~RaiseInfo(); +}; +//__________________________________________________________________________________________________ +RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) + : _n0( 0 ) + , _pDtor( new ObjectFunction( pTypeDescr, destruct ) ) + , _n2( 0 ) + , _n3( 0 ) + , _n4( 0 ) +{ + // a must be + OSL_ENSHURE( sizeof(sal_Int32) == sizeof(ExceptionType *), "### pointer size differs from sal_Int32!" ); + + typelib_CompoundTypeDescription * pCompTypeDescr; + + // info count + sal_Int32 nLen = 0; + for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr; + pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription ) + { + ++nLen; + } + + // info count accompanied by type info ptrs: type, base type, base base type, ... + _types = rtl_allocateMemory( sizeof(sal_Int32) + (sizeof(ExceptionType *) * nLen) ); + *(sal_Int32 *)_types = nLen; + + ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1); + + sal_Int32 nPos = 0; + for ( pCompTypeDescr = (typelib_CompoundTypeDescription*)pTypeDescr; + pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription ) + { + ppTypes[nPos++] = new ExceptionType( (typelib_TypeDescription *)pCompTypeDescr ); + } +} +//__________________________________________________________________________________________________ +RaiseInfo::~RaiseInfo() +{ + ExceptionType ** ppTypes = (ExceptionType **)((sal_Int32 *)_types + 1); + for ( sal_Int32 nTypes = *(sal_Int32 *)_types; nTypes--; ) + delete ppTypes[nTypes]; + rtl_freeMemory( _types ); + + delete _pDtor; +} + +//================================================================================================== +class ExceptionInfos +{ + Mutex _aMutex; + t_string2PtrMap _allRaiseInfos; +public: + void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ); + + ExceptionInfos(); + ~ExceptionInfos(); +}; +//__________________________________________________________________________________________________ +ExceptionInfos::ExceptionInfos() +{ +} +//__________________________________________________________________________________________________ +ExceptionInfos::~ExceptionInfos() +{ + TRACE( "> freeing exception infos... <\n" ); + + MutexGuard aGuard( _aMutex ); + for ( t_string2PtrMap::const_iterator iPos( _allRaiseInfos.begin() ); + iPos != _allRaiseInfos.end(); ++iPos ) + { + delete (RaiseInfo *)(*iPos).second; + } +} +//__________________________________________________________________________________________________ +void ExceptionInfos::raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +{ + // construct cpp exception object + typelib_TypeDescription * pTypeDescr = 0; + TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType ); + + OSL_ENSHURE( pTypeDescr && (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT || + pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION), + "### can only throw types of class exception/ structs" ); + + void * pCppExc = alloca( pTypeDescr->nSize ); + uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp ); + + // concatenate all types of exception for key + OUStringBuffer aKeyBuf; + typelib_CompoundTypeDescription * pCompTypeDescr; + for ( pCompTypeDescr = (typelib_CompoundTypeDescription *)pTypeDescr; + pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription ) + { + aKeyBuf.append( ((typelib_TypeDescription *)pCompTypeDescr)->pTypeName ); + } + OString aKey( OUStringToOString( aKeyBuf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) ); + + MutexGuard aGuard( _aMutex ); + const t_string2PtrMap::const_iterator iFind( _allRaiseInfos.find( aKey ) ); + + // a must be + OSL_ENSHURE( sizeof(sal_Int32) == sizeof(void *), "### pointer size differs from sal_Int32!" ); + DWORD arFilterArgs[3]; + arFilterArgs[0] = 0x19930520L; + arFilterArgs[1] = (DWORD)pCppExc; + arFilterArgs[2] = (DWORD)(iFind != _allRaiseInfos.end() + ? (*iFind).second // reuse existing info + : _allRaiseInfos[aKey] = new RaiseInfo( pTypeDescr )); // put into map + + // this is the last chance to release anything not affected by stack unwinding: + // destruct uno exception + uno_any_destruct( pUnoExc, 0 ); + + TYPELIB_DANGER_RELEASE( pTypeDescr ); + + RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs ); +} + + +//################################################################################################## +//#### exported #################################################################################### +//################################################################################################## + + +//################################################################################################## +type_info * msci_getRTTI( const OString & rUNOname ) +{ + static RTTInfos * s_pRTTIs = 0; + if (! s_pRTTIs) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pRTTIs) + { +#ifdef LEAK_STATIC_DATA + s_pRTTIs = new RTTInfos(); +#else + static RTTInfos s_aRTTIs; + s_pRTTIs = &s_aRTTIs; +#endif + } + } + return s_pRTTIs->getRTTI( rUNOname ); +} + +//################################################################################################## +void msci_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ) +{ + static ExceptionInfos * s_pInfos = 0; + if (! s_pInfos) + { + MutexGuard aGuard( Mutex::getGlobalMutex() ); + if (! s_pInfos) + { +#ifdef LEAK_STATIC_DATA + s_pInfos = new ExceptionInfos(); +#else + static ExceptionInfos s_allExceptionInfos; + s_pInfos = &s_allExceptionInfos; +#endif + } + } + s_pInfos->raiseException( pUnoExc, pUno2Cpp ); +} + +//################################################################################################## +sal_Int32 msci_filterCppException( + LPEXCEPTION_POINTERS pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno ) +{ + PEXCEPTION_RECORD pRecord = pPointers->ExceptionRecord; + if (pRecord->ExceptionCode == MSVC_ExceptionCode && + pRecord->ExceptionFlags == EXCEPTION_NONCONTINUABLE && + pRecord->NumberParameters == 3 && +// pRecord->ExceptionInformation[0] == 0x19930520 && + pRecord->ExceptionInformation[1] && + pRecord->ExceptionInformation[2]) + { + void * types = ((RaiseInfo *)pRecord->ExceptionInformation[2])->_types; + if (types && *(sal_Int32 *)types) // count + { + ExceptionType * pType = *(ExceptionType **)((sal_Int32 *)types +1); + if (pType && pType->_pTypeInfo) + { + OUString aUNOname( OStringToOUString( toUNOname( + ((__type_info *)pType->_pTypeInfo)->_m_d_name ), RTL_TEXTENCODING_ASCII_US ) ); + typelib_TypeDescription * pExcTypeDescr = 0; + typelib_typedescription_getByName( &pExcTypeDescr, aUNOname.pData ); + + if (pExcTypeDescr) + { + // construct uno exception any + uno_any_constructAndConvert( pUnoExc, (void *)pRecord->ExceptionInformation[1], + pExcTypeDescr, pCpp2Uno ); + uno_destructData( (void *)pRecord->ExceptionInformation[1], + pExcTypeDescr, cpp_release ); + typelib_typedescription_release( pExcTypeDescr ); + return EXCEPTION_EXECUTE_HANDLER; + } + } + } + } + return EXCEPTION_CONTINUE_SEARCH; +} + +} + +#pragma pack(pop) + diff --git a/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk new file mode 100644 index 000000000000..31435863d82a --- /dev/null +++ b/bridges/source/cpp_uno/msvc_win32_intel/makefile.mk @@ -0,0 +1,119 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ +# +# 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=msci_uno +TARGET=msci_uno +LIBTARGET=no +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- +.IF "$(COM)" == "MSC" + +.IF "$(debug)" == "" +CFLAGS += /O2gityb2 /Gs +.ELSE +CFLAGS += /Ob0 +.ENDIF + +SLOFILES= \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj \ + $(SLO)$/except.obj + +SHL1TARGET= $(TARGET) + +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +SHL1IMPLIB= i$(TARGET) + +SHL1OBJS= \ + $(SLO)$/cpp2uno.obj \ + $(SLO)$/uno2cpp.obj \ + $(SLO)$/except.obj + +SHL1STDLIBS= \ + $(CPPULIB) \ + $(SALLIB) + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +$(MISC)$/$(SHL1TARGET).def: makefile.mk + @echo ------------------------------ + @echo Making: $@ + @echo LIBRARY $(SHL1TARGET) >$@ + @echo DESCRIPTION 'MS Visual C++ bridge to UNO' >>$@ + @echo DATA READ WRITE NONSHARED >>$@ + @echo EXPORTS >>$@ + @echo uno_initEnvironment @3 >>$@ + @echo uno_ext_getMapping @4 >>$@ + +.ENDIF + diff --git a/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx new file mode 100644 index 000000000000..c934158a9ac2 --- /dev/null +++ b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * $RCSfile: msci.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ + * + * 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 <windows.h> + +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif + +#define MSVC_ExceptionCode 0xe06d7363 + +class type_info; +typedef struct _uno_Any uno_Any; +typedef struct _uno_Mapping uno_Mapping; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +type_info * msci_getRTTI( + const ::rtl::OString & rUNOname ); + +//================================================================================================== +sal_Int32 msci_filterCppException( + LPEXCEPTION_POINTERS pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno ); + +//================================================================================================== +void msci_raiseException( + uno_Any * pUnoExc, uno_Mapping * pUno2Cpp ); + +} + diff --git a/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx new file mode 100644 index 000000000000..c0fa7227d3d5 --- /dev/null +++ b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx @@ -0,0 +1,494 @@ +/************************************************************************* + * + * $RCSfile: uno2cpp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + +#pragma warning( disable : 4237 ) +#include <malloc.h> +#ifndef _RTL_ALLOC_H_ +#include <rtl/alloc.h> +#endif +#ifndef _RTL_STRING_HXX_ +#include <rtl/string.hxx> +#endif + +#ifndef _UNO_DATA_H_ +#include <uno/data.h> +#endif +#ifndef _BRIDGES_CPP_UNO_BRIDGE_HXX_ +#include <bridges/cpp_uno/bridge.hxx> +#endif +#ifndef _BRIDGES_CPP_UNO_TYPE_MISC_HXX_ +#include <bridges/cpp_uno/type_misc.hxx> +#endif + +#include "msci.hxx" + +using namespace rtl; +using namespace com::sun::star::uno; + +namespace CPPU_CURRENT_NAMESPACE +{ + +//================================================================================================== +inline static void callVirtualMethod( void * pThis, sal_Int32 nVtableIndex, + void * pRegisterReturn, typelib_TypeClass eReturnTypeClass, + sal_Int32 * pStackLongs, sal_Int32 nStackLongs ) +{ + // parameter list is mixed list of * and values + // reference parameters are pointers + + OSL_ENSHURE( pStackLongs && pThis, "### null ptr!" ); + OSL_ENSHURE( (sizeof(void *) == 4) && + (sizeof(sal_Int32) == 4), "### unexpected size of int!" ); + +__asm + { + mov eax, nStackLongs + test eax, eax + je Lcall + // copy values + mov ecx, eax + shl eax, 2 // sizeof(sal_Int32) == 4 + add eax, pStackLongs // params stack space +Lcopy: sub eax, 4 + push dword ptr [eax] + dec ecx + jne Lcopy +Lcall: + // call + mov ecx, pThis + push ecx // this ptr + mov edx, [ecx] // pvft + mov eax, nVtableIndex + shl eax, 2 // sizeof(void *) == 4 + add edx, eax + call [edx] // interface method call must be __cdecl!!! + + // register return + mov ecx, eReturnTypeClass + cmp ecx, typelib_TypeClass_VOID + je Lcleanup + mov ebx, pRegisterReturn +// int32 + cmp ecx, typelib_TypeClass_LONG + je Lint32 + cmp ecx, typelib_TypeClass_UNSIGNED_LONG + je Lint32 + cmp ecx, typelib_TypeClass_ENUM + je Lint32 +// int8 + cmp ecx, typelib_TypeClass_BOOLEAN + je Lint8 + cmp ecx, typelib_TypeClass_BYTE + je Lint8 +// int16 + cmp ecx, typelib_TypeClass_CHAR + je Lint16 + cmp ecx, typelib_TypeClass_SHORT + je Lint16 + cmp ecx, typelib_TypeClass_UNSIGNED_SHORT + je Lint16 +// float + cmp ecx, typelib_TypeClass_FLOAT + je Lfloat +// double + cmp ecx, typelib_TypeClass_DOUBLE + je Ldouble +// int64 + cmp ecx, typelib_TypeClass_HYPER + je Lint64 + cmp ecx, typelib_TypeClass_UNSIGNED_HYPER + je Lint64 + jmp Lcleanup // no simple type +Lint8: + mov byte ptr [ebx], al + jmp Lcleanup +Lint16: + mov word ptr [ebx], ax + jmp Lcleanup +Lfloat: + fstp dword ptr [ebx] + jmp Lcleanup +Ldouble: + fstp qword ptr [ebx] + jmp Lcleanup +Lint64: + mov dword ptr [ebx], eax + mov dword ptr [ebx+4], edx + jmp Lcleanup +Lint32: + mov dword ptr [ebx], eax + jmp Lcleanup +Lcleanup: + // cleanup stack (obsolete though because of function) + mov eax, nStackLongs + shl eax, 2 // sizeof(sal_Int32) == 4 + add eax, 4 // this ptr + add esp, eax + } +} + +//================================================================================================== +inline static void cpp_call( + cppu_unoInterfaceProxy * pThis, + sal_Int32 nVtableCall, + typelib_TypeDescriptionReference * pReturnTypeRef, + sal_Int32 nParams, typelib_MethodParameter * pParams, + sal_Int32 nExceptions, typelib_TypeDescriptionReference ** ppExceptionRefs, + void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc ) +{ + // max space for: [complex ret ptr], values|ptr ... + char * pCppStack = (char *)alloca( sizeof(sal_Int32) + (nParams * sizeof(sal_Int64)) ); + char * pCppStackStart = pCppStack; + + // return + typelib_TypeDescription * pReturnTypeDescr = 0; + TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef ); + OSL_ENSHURE( 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 *); + } + } + + // stack space + + OSL_ENSHURE( 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 + } + + // only try-finally/ try-except statements possible... + __try + { + __try + { + // pCppI is msci this pointer + callVirtualMethod( + pThis->pCppI, nVtableCall, + pCppReturn, pReturnTypeDescr->eTypeClass, + (sal_Int32 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_Int32) ); + + // NO exception occured... + *ppUnoExc = 0; + + // reconvert temporary params + while (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 ); + } + } + __except (msci_filterCppException( GetExceptionInformation(), + *ppUnoExc, &pThis->pBridge->aCpp2Uno )) + { + // *ppUnoExc is untouched and any was constructed by filter function + // __finally block will be called + return; + } + } + __finally + { + // cleanup of params was already done in reconversion loop iff no exception occured; + // this is quicker than getting all param descriptions twice! + // so cleanup only iff an exception occured: + if (*ppUnoExc) + { + // temporary params + while (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 ) +{ + // is my surrogate + cppu_unoInterfaceProxy * pThis = static_cast< 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_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); + + sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos]; + OSL_ENSHURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" ); + + typelib_TypeDescriptionReference * pRuntimeExcRef = 0; + + if (pReturn) + { + // dependent dispatch + cpp_call( pThis, nVtableCall, + ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef, + 0, 0, // no params + 1, &pRuntimeExcRef, // RuntimeException + 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, + 1, &pRuntimeExcRef, + 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_ENSHURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" ); + + sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos]; + OSL_ENSHURE( 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() ); + OSL_ASSERT( 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, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nExceptions, + ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->ppExceptions, + pReturn, pArgs, ppException ); + } + break; + } + default: + { + ::com::sun::star::uno::RuntimeException aExc( + OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ), + pThis->pCppI ); + + typelib_TypeDescription * pTD = 0; + const Type & rExcType = ::getCppuType( (const ::com::sun::star::uno::RuntimeException *)0 ); + TYPELIB_DANGER_GET( &pTD, rExcType.getTypeLibType() ); + uno_any_construct( *ppException, &aExc, pTD, 0 ); + TYPELIB_DANGER_RELEASE( pTD ); + } + } +} + +} + diff --git a/bridges/source/remote/context/context.cxx b/bridges/source/remote/context/context.cxx new file mode 100644 index 000000000000..8e7ffc7763cc --- /dev/null +++ b/bridges/source/remote/context/context.cxx @@ -0,0 +1,552 @@ +/************************************************************************* + * + * $RCSfile: context.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ + * + * 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 <list> +#include <hash_map> +#include <utility> + +#include <osl/diagnose.h> +#include <osl/interlck.h> +#include <osl/mutex.hxx> + +#include <rtl/ustring> + +#include <bridges/remote/context.h> +#include <bridges/remote/remote.h> +#include <bridges/remote/connection.h> + +using namespace ::std; +using namespace ::osl; +using namespace ::rtl; + +namespace remote_context +{ + +class remote_ContextImpl : + public remote_Context +{ +public: + remote_ContextImpl( remote_Connection *pConnection, + rtl_uString *pIdStr, + rtl_uString *pDescription, + rtl_uString *pProtocol, + remote_InstanceProvider *pProvider ); + ~remote_ContextImpl(); + + static void SAL_CALL thisAcquire( uno_Context * ); + static void SAL_CALL thisRelease( uno_Context * ); + static void * SAL_CALL thisQuery( uno_Context * , rtl_uString * ); + static void SAL_CALL thisAddDisposingListener( remote_Context * , remote_DisposingListener * ); + static void SAL_CALL thisRemoveDisposingListener( remote_Context *, remote_DisposingListener *); + static void SAL_CALL thisDispose( remote_Context *); +public: + oslInterlockedCount m_nRef; + sal_Bool m_bDisposed; + list < remote_DisposingListener * > m_lstListener; + Mutex m_mutex; +}; + + + + +struct equalOUString_Impl +{ + sal_Bool operator()(const OUString & s1, const OUString & s2) const + { return s1 == s2; } +}; + +struct hashOUString_Impl +{ + size_t operator()(const OUString & rName) const + { return rName.hashCode(); } +}; + +typedef hash_map +< + OUString, + void *, + hashOUString_Impl, + equalOUString_Impl +> +ContextMap; + +#ifdef DEBUG +struct MyCounter +{ + MyCounter( sal_Char *pName ) : + m_pName ( pName ), + m_nCounter( 0 ) + { + } + ~MyCounter() + { + if( m_nCounter ) { + printf( "%s : %d left\n", m_pName , m_nCounter ); + } + } + void acquire() + { m_nCounter ++; } + void release() + { m_nCounter --; } + + + sal_Int32 m_nCounter; + sal_Char *m_pName; +}; +static MyCounter thisCounter( "DEBUG : Context" ); +#endif + +class ContextAdmin; + +ContextAdmin *g_pTheContext = 0; + + + +class ContextAdmin +{ +public: + static ContextAdmin *getInstance(); + + // listener administration + void addContextListener( remote_contextListenerFunc listener , void *pObject ); + void removeContextListener( remote_contextListenerFunc listener , void *pObject ); + + void fire( sal_Int32 nRemoteContextMode, + rtl_uString *sName, + rtl_uString *sDescription ); + + // context administration + uno_Context *createAndRegisterContext( + remote_Connection *pConnection, + rtl_uString *pIdStr, + rtl_uString *pDescription, + rtl_uString *pProtocol, + remote_InstanceProvider *pInstanceProvider ); + + void revokeContext( uno_Context *pRemoteContext ); + + uno_Context *get( rtl_uString *pHost ); + + rtl_uString ** getConnectionList( + sal_Int32 *pnStringCount , + void * ( SAL_CALL * memAlloc ) ( sal_uInt32 nBytesToAlloc ) ); + +private: + ::osl::Mutex m_mutex; + + ContextMap m_mapContext; + + ::std::list< ::std::pair< void *, void *> > m_lstListener; +}; + +ContextAdmin *ContextAdmin::getInstance() +{ + if( ! g_pTheContext ) { + ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() ); + if( ! g_pTheContext ) { + static ContextAdmin admin; + g_pTheContext = &admin; + } + } + return g_pTheContext; +} + +void ContextAdmin::addContextListener( remote_contextListenerFunc listener , void *pObject ) +{ + ::osl::MutexGuard guard( m_mutex ); + + m_lstListener.push_back( ::std::pair< void * , void * > ( (void*) listener , pObject ) ); +} + +void ContextAdmin::removeContextListener( remote_contextListenerFunc listener , void *pObject ) +{ + ::osl::MutexGuard guard( m_mutex ); + + for( ::std::list< ::std::pair< void *, void *> >::iterator ii = m_lstListener.begin() ; + ii != m_lstListener.end() ; + ++ii ) + { + if( (*ii).first == (void*)listener && + (*ii).second == (void*)pObject ) + { + m_lstListener.erase( ii ); + break; + } + } +} + +void ContextAdmin::fire( + sal_Int32 nRemoteContextMode, + rtl_uString *pName, + rtl_uString *sDescription ) +{ + ::osl::MutexGuard guard( m_mutex ); + ::std::list< ::std::pair< void *, void *> > lstListener = m_lstListener; + + for( ::std::list< ::std::pair< void *, void *> >::iterator ii = lstListener.begin() ; + ii != lstListener.end(); + ++ii) + { + remote_contextListenerFunc listener = (remote_contextListenerFunc) (*ii).first; + listener( (*ii).second , nRemoteContextMode , pName, sDescription ); + } +} + +uno_Context *ContextAdmin::createAndRegisterContext( remote_Connection *pConnection, + rtl_uString *pIdStr, + rtl_uString *pDescription, + rtl_uString *pProtocol, + remote_InstanceProvider *pInstanceProvider ) +{ + ::osl::MutexGuard guard( m_mutex ); + + uno_Context *pContext = get( pIdStr ); + if( pContext ) + { + pContext->release( pContext ); + return 0; + } + + remote_ContextImpl *p = new remote_ContextImpl( pConnection, + pIdStr, + pDescription, + pProtocol, + pInstanceProvider ); + + p->aBase.acquire( (uno_Context*) p ); + + m_mapContext[ OUString( pIdStr) ] = (void*) p; + + fire( REMOTE_CONTEXT_CREATE , pIdStr , pDescription ); + return ( uno_Context * )p; +} + + +void ContextAdmin::revokeContext( uno_Context *pRemoteContext ) +{ + ::osl::MutexGuard guard( m_mutex ); + + remote_ContextImpl *p = ( remote_ContextImpl * ) pRemoteContext; + + ContextMap::iterator ii = m_mapContext.find( p->m_pName ); + OSL_ASSERT( ii != m_mapContext.end() ); + m_mapContext.erase( ii ); + + fire( REMOTE_CONTEXT_DESTROY , p->m_pName , p->m_pDescription ); + +} + +uno_Context *ContextAdmin::get( rtl_uString *pHost ) +{ + ::osl::MutexGuard guard( m_mutex ); + + ContextMap::iterator ii = m_mapContext.find( OUString( (rtl_uString*)pHost ) ); + if( ii == m_mapContext.end() ) + { + return 0; + } + + uno_Context *p = ( uno_Context * ) (*ii).second; + p->acquire( p ); + return p; +} + + +rtl_uString ** ContextAdmin::getConnectionList( + sal_Int32 *pnStringCount , + void * ( SAL_CALL * memAlloc ) ( sal_uInt32 nBytesToAlloc ) ) +{ + ::osl::MutexGuard guard( m_mutex ); + + *pnStringCount = m_mapContext.size(); + rtl_uString **ppReturn = ( rtl_uString ** ) + memAlloc( sizeof( rtl_uString * ) * m_mapContext.size() ); + memset( ppReturn , 0 , sizeof( rtl_uString * ) * m_mapContext.size() ); + + sal_Int32 i = 0; + for( ContextMap::iterator ii = m_mapContext.begin() ; + ii != m_mapContext.end(); + ++ii, i++ ) + { + rtl_uString_assign( &( ppReturn[i] ), (*ii).first.pData ); + } + + return ppReturn; +} + + + +/***************************** + * remote_ContextImpl implementation + ****************************/ + + + +remote_ContextImpl::remote_ContextImpl( remote_Connection *pConnection , + rtl_uString *pIdStr, + rtl_uString *pDescription, + rtl_uString *pProtocol, + remote_InstanceProvider *pProvider ) : + m_nRef( 0 ), + m_bDisposed( sal_False ) +{ + m_pConnection = pConnection; + m_pConnection->acquire( m_pConnection ); + + m_pInstanceProvider = pProvider; + if( m_pInstanceProvider ) + { + m_pInstanceProvider->acquire( pProvider ); + } + + m_pName = pIdStr; + rtl_uString_acquire( m_pName ); + + m_pDescription = pDescription; + rtl_uString_acquire( m_pDescription ); + + m_pProtocol = pProtocol; + rtl_uString_acquire( pProtocol ); + + aBase.acquire = thisAcquire; + aBase.release = thisRelease; + addDisposingListener = thisAddDisposingListener; + removeDisposingListener = thisRemoveDisposingListener; + dispose = thisDispose; +#ifdef DEBUG + thisCounter.acquire(); +#endif +} + +remote_ContextImpl::~remote_ContextImpl() +{ + // disposed must have been called + OSL_ASSERT( m_bDisposed ); + + rtl_uString_release( m_pName ); + rtl_uString_release( m_pDescription ); + rtl_uString_release( m_pProtocol ); +#ifdef DEBUG + thisCounter.release(); +#endif + +} + + +void remote_ContextImpl::thisAddDisposingListener( remote_Context *pRemoteC , + remote_DisposingListener *pListener ) +{ + remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC; + + ::osl::MutexGuard guard( pImpl->m_mutex ); + + pListener->acquire( pListener ); + pImpl->m_lstListener.push_back( pListener ); +} + +void remote_ContextImpl::thisRemoveDisposingListener( remote_Context *pRemoteC, + remote_DisposingListener *pListener) +{ + remote_ContextImpl *pImpl = (remote_ContextImpl * ) pRemoteC; + MutexGuard guard( pImpl->m_mutex ); + + for( list< remote_DisposingListener * >::iterator ii = pImpl->m_lstListener.begin() ; + ii != pImpl->m_lstListener.end(); + ++ii ) + { + if( (*ii) == pListener ) + { + pImpl->m_lstListener.erase( ii ); + pListener->release( pListener ); + break; + } + } +} + +void remote_ContextImpl::thisDispose( remote_Context *pRemoteC ) +{ + remote_ContextImpl *pImpl = ( remote_ContextImpl * )pRemoteC; + + MutexGuard guard( pImpl->m_mutex ); + if( ! pImpl->m_bDisposed ) + { + pImpl->m_bDisposed = sal_True; + ContextAdmin::getInstance()->revokeContext( (uno_Context * ) pRemoteC ); + + if( pImpl->m_pInstanceProvider ) + { + pImpl->m_pInstanceProvider->release( pImpl->m_pInstanceProvider ); + pImpl->m_pInstanceProvider = 0; + } + + pImpl->m_pConnection->release( pImpl->m_pConnection ); + pImpl->m_pConnection = 0; + + list< remote_DisposingListener * > lst = pImpl->m_lstListener; + pImpl->m_lstListener.clear(); + + for( list < remote_DisposingListener * >::iterator ii = lst.begin(); + ii != lst.end(); + ++ii ) + { + (*ii)->disposing( (*ii) , pImpl->m_pName ); + (*ii)->release( (*ii) ); + } + + } +} + + + +void remote_ContextImpl::thisAcquire( uno_Context *pRemoteC ) +{ + remote_ContextImpl *p = SAL_REINTERPRET_CAST(remote_ContextImpl * ,pRemoteC ); + osl_incrementInterlockedCount( &(p->m_nRef) ); +} + +void remote_ContextImpl::thisRelease( uno_Context *pRemoteC ) +{ + remote_ContextImpl *p = SAL_REINTERPRET_CAST( remote_ContextImpl * , pRemoteC ); + if (! osl_decrementInterlockedCount( &(p->m_nRef) )) + { + // enshure, that this piece of code is not reentered + osl_incrementInterlockedCount( &(p->m_nRef) ); + + // dispose, if necessary + p->dispose( p ); + + // restore the counter + osl_decrementInterlockedCount( &(p->m_nRef) ); + + if( 0 == p->m_nRef ) + { + delete p; + } + else + { + // reanimated, but disposed ! + } + } +} + +void *remote_ContextImpl::thisQuery( uno_Context * , rtl_uString * ) +{ + return 0; +} + + +} // end namespace remote_context + + +using namespace remote_context; + +//----------------------- +// +// C-Interface +// +//----------------------- +extern "C" SAL_DLLEXPORT remote_Context * SAL_CALL +remote_getContext( rtl_uString *pIdString ) +{ + return (remote_Context *) ContextAdmin::getInstance()->get( pIdString ); +} + + + +extern "C" SAL_DLLEXPORT remote_Context * SAL_CALL +remote_createContext( remote_Connection *pConnection, + rtl_uString *pIdStr, + rtl_uString *pDescription, + rtl_uString *pProtocol, + remote_InstanceProvider *pProvider ) +{ + remote_ContextImpl *p = (remote_ContextImpl * ) + ContextAdmin::getInstance()->createAndRegisterContext( + pConnection , + pIdStr , + pDescription, + pProtocol, + pProvider ); + + return (remote_Context * )p; +} + + +extern "C" SAL_DLLEXPORT void SAL_CALL +remote_addContextListener( remote_contextListenerFunc listener, void *pObject ) +{ + ContextAdmin::getInstance()->addContextListener( listener , pObject ); +} + +extern "C" SAL_DLLEXPORT void SAL_CALL +remote_removeContextListener( remote_contextListenerFunc listener , void *pObject ) +{ + ContextAdmin::getInstance()->removeContextListener( listener , pObject ); +} + +extern "C" SAL_DLLEXPORT rtl_uString ** SAL_CALL +remote_getContextList( + sal_Int32 *pnStringCount, + void * ( SAL_CALL * memAlloc ) ( sal_uInt32 nBytesToAlloc ) ) +{ + return ContextAdmin::getInstance()->getConnectionList( pnStringCount , memAlloc ); +} diff --git a/bridges/source/remote/context/exports.dxp b/bridges/source/remote/context/exports.dxp new file mode 100644 index 000000000000..dcef3c369b10 --- /dev/null +++ b/bridges/source/remote/context/exports.dxp @@ -0,0 +1,5 @@ +remote_getContext +remote_createContext +remote_getContextList +remote_removeContextListener +remote_addContextListener
\ No newline at end of file diff --git a/bridges/source/remote/context/makefile.mk b/bridges/source/remote/context/makefile.mk new file mode 100644 index 000000000000..0d74b2d01dd6 --- /dev/null +++ b/bridges/source/remote/context/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ +# +# 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=rmcxt +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk +.INCLUDE : $(PRJ)$/version.mk +# ------------------------------------------------------------------ + +UNOUCRDEP=$(SOLARUCRDIR)$/uce.rdb +UNOUCRRDB=$(SOLARUCRDIR)$/uce.rdb + +# output directory (one dir for each project) +UNOUCROUT=$(OUT)$/inc$/$(PRJNAME)$/$(TARGET) + +# adding to inludepath +INCPRE+=$(UNOUCROUT) + +UNOTYPES= + +SLOFILES= $(SLO)$/context.obj + +SHL1TARGET= $(RMCXT_TARGET)$(RMCXT_MAJOR) + +SHL1STDLIBS= \ + $(VOSLIB) \ + $(SALLIB) + +SHL1DEPN= +SHL1IMPLIB= i$(TARGET) +SHL1LIBS= $(SLB)$/$(TARGET).lib +SHL1DEF= $(MISC)$/$(SHL1TARGET).def + +DEF1NAME= $(SHL1TARGET) +DEF1EXPORTFILE= exports.dxp + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/bridges/source/remote/idl/corba.idl b/bridges/source/remote/idl/corba.idl new file mode 100644 index 000000000000..7c7971d43f05 --- /dev/null +++ b/bridges/source/remote/idl/corba.idl @@ -0,0 +1,122 @@ +/************************************************************************* + * + * $RCSfile: corba.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:49 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +module com +{ +module sun +{ +module star +{ + +module corba +{ + + // CosBridging module + typedef unsigned long ObjectSystemID; + typedef sequence< byte > OpaqueData; + + struct OneThreadID + { + ObjectSystemID objSysID; + OpaqueData threadID; + }; + + typedef sequence<OneThreadID> ThreadIDs; + + struct LogicalThreadID // Service context + { + ThreadIDs IDs; + }; + + struct CorbaString8 + { + string theString; + }; + + struct CorbaUnion + { + long dummy; + }; + + struct ObjectKey + { + CorbaString8 sOid; + CorbaString8 sType; + }; + + enum TCKind + { + tk_null, tk_void, + tk_short, tk_long, tk_ushort, tk_ulong, + tk_float, tk_double, tk_boolean, tk_char, + tk_octet, tk_any, tk_TypeCode, tk_Principal, tk_objref, + tk_struct, tk_union, tk_enum, tk_string, + tk_sequence, tk_array, tk_alias, tk_except, + tk_longlong, tk_ulonglong, tk_longdouble, + tk_wchar, tk_wstring, tk_fixed, + tk_value, tk_value_box, + tk_native, + tk_abstract_interface + }; +}; + +}; +}; +}; diff --git a/bridges/source/remote/static/helper.cxx b/bridges/source/remote/static/helper.cxx new file mode 100644 index 000000000000..5fbd68350771 --- /dev/null +++ b/bridges/source/remote/static/helper.cxx @@ -0,0 +1,232 @@ +/************************************************************************* + * + * $RCSfile: helper.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <rtl/alloc.h> +#include <osl/diagnose.h> + +#include <bridges/remote/helper.hxx> + +#include <bridges/remote/stub.hxx> +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/remote.hxx> + +#include <com/sun/star/uno/Sequence.hxx> + +using namespace ::rtl; +using namespace ::com::sun::star::uno; + +namespace bridges_remote +{ + +void SAL_CALL remote_createStub ( + remote_Interface **ppRemoteI, + rtl_uString *pOid , + typelib_TypeDescriptionReference *pTypeRef, + uno_Environment *pEnvRemote ) +{ + typelib_TypeDescription *pType = 0; + typelib_typedescriptionreference_getDescription( &pType, pTypeRef ); + + pEnvRemote->pExtEnv->getRegisteredInterface( + pEnvRemote->pExtEnv, + (void **)ppRemoteI, + pOid, + (typelib_InterfaceTypeDescription* )pType ); + + if( *ppRemoteI ) + { + if( (*ppRemoteI)->acquire == ::bridges_remote::Remote2RemoteStub::thisAcquire ) { + + // send a release to remote + ((::bridges_remote::Remote2RemoteStub *)*ppRemoteI)->releaseRemote(); + } + else + { + // Uno2RemoteStub + // no release necessary + } + } + else + { + remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl; + *ppRemoteI = + new ::bridges_remote::Remote2RemoteStub( + pOid, + (typelib_InterfaceTypeDescription * ) pType, + pEnvRemote, + pImpl->m_sendRequest); + + // ppRemoteI may change during registration + pEnvRemote->pExtEnv->registerProxyInterface( + pEnvRemote->pExtEnv, + (void **) ppRemoteI, + ::bridges_remote::Remote2RemoteStub::thisFree, + pOid, + (typelib_InterfaceTypeDescription * ) pType ); + } + + typelib_typedescription_release( pType ); +} + +void SAL_CALL remote_sendQueryInterface( + uno_Environment *pEnvRemote, + remote_Interface **ppRemoteI, + rtl_uString *pOid , + typelib_TypeDescriptionReference *pTypeRef + ) +{ + OSL_ASSERT( ppRemoteI ); + + typelib_InterfaceTypeDescription *pType = 0; + typelib_typedescriptionreference_getDescription( (typelib_TypeDescription ** )&pType, pTypeRef ); + + if( *ppRemoteI ) + { + (*ppRemoteI)->release( *ppRemoteI ); + (*ppRemoteI) = 0; + } + + remote_BridgeImpl *pImpl = ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl; + + Type type = ::getCppuType( (Reference < XInterface > *)0 ); + + // get type for queryInterface + OUString sCompleteMethodName = type.getTypeName(); + sCompleteMethodName += OUString::createFromAscii("::queryInterface"); + + typelib_InterfaceMemberTypeDescription *pMemberType = 0; + typelib_typedescription_getByName( + (typelib_TypeDescription **) &pMemberType, + sCompleteMethodName.pData ); + + OSL_ASSERT( pMemberType ); + + uno_Any anyInterface; + anyInterface.pType = 0; + anyInterface.pData = 0; + + void *pReturn = &anyInterface; + void *ppArgs[1]; + + ppArgs[0] = 0; + typelib_TypeDescriptionReference *pRef = 0; + typelib_typedescriptionreference_new( &pRef , + pType->aBase.eTypeClass, + pType->aBase.pTypeName); + + ppArgs[0] = &pRef; + + uno_Any anyException; + uno_Any *pAnyException = &anyException; + + // do the queryInterface + pImpl->m_sendRequest( + pEnvRemote, + (typelib_TypeDescription * ) pMemberType, + pOid, + pType, + pReturn, + ppArgs, + &pAnyException ); + + + // now release everything + typelib_typedescriptionreference_release( pRef ); + typelib_typedescription_release( (typelib_TypeDescription * ) pMemberType ); + + if( pAnyException ) + { + uno_any_destruct( pAnyException , 0 ); + } + else + { + // set out parameter + if( typelib_TypeClass_INTERFACE == anyInterface.pType->eTypeClass ) + { + *ppRemoteI = *( remote_Interface ** ) anyInterface.pData; + rtl_freeMemory( anyInterface.pData ); + } + typelib_typedescriptionreference_release( anyInterface.pType ); + } + + typelib_typedescription_release( (typelib_TypeDescription * ) pType ); +} + + +void SAL_CALL remote_retrieveOidFromProxy( + remote_Interface *pRemoteI, + rtl_uString **ppOid ) +{ + if( pRemoteI->acquire == ::bridges_remote::Remote2RemoteStub::thisAcquire ) + { + // Remote2RemoteStub + ::bridges_remote::Remote2RemoteStub *pStub = (::bridges_remote::Remote2RemoteStub * ) pRemoteI; + rtl_uString_newFromString( ppOid , pStub->m_sOid.pData ); + } + else + { + // Uno2RemoteStub + ::bridges_remote::Uno2RemoteStub *pStub = (::bridges_remote::Uno2RemoteStub * ) pRemoteI; + rtl_uString_newFromString( ppOid , pStub->m_sOid.pData ); + pRemoteI->acquire( pRemoteI ); + } +} + +} diff --git a/bridges/source/remote/static/makefile.mk b/bridges/source/remote/static/makefile.mk new file mode 100644 index 000000000000..22f2b2516a91 --- /dev/null +++ b/bridges/source/remote/static/makefile.mk @@ -0,0 +1,107 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ +# +# 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=bridges_remote_static +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +BRIDGES_MARSHALLIB = bridges_marshal.lib +#CPPUMAKERFLAGS += -C +UNOUCRDEP=$(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb + +# output directory (one dir for each project) +UNOUCROUT=$(OUT)$/inc + +# adding to inludepath +INCPRE+=$(UNOUCROUT) + +UNOTYPES= com.sun.star.uno.XInterface \ + com.sun.star.uno.TypeClass + + +SLOFILES= \ + $(SLO)$/proxy.obj \ + $(SLO)$/stub.obj \ + $(SLO)$/remote.obj \ + $(SLO)$/mapping.obj \ + $(SLO)$/helper.obj \ + $(SLO)$/remote_types.obj + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + diff --git a/bridges/source/remote/static/mapping.cxx b/bridges/source/remote/static/mapping.cxx new file mode 100644 index 000000000000..91706e5aab7e --- /dev/null +++ b/bridges/source/remote/static/mapping.cxx @@ -0,0 +1,250 @@ +/************************************************************************* + * + * $RCSfile: mapping.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <osl/diagnose.h> + +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/stub.hxx> +#include <bridges/remote/counter.hxx> +#include <bridges/remote/mapping.hxx> + +namespace bridges_remote { + +RemoteMapping::RemoteMapping( uno_Environment *pEnvUno_ , + uno_Environment *pEnvRemote_, + uno_MapInterfaceFunc func, + const ::rtl::OUString sPurpose) : + m_nRef( 1 ), + m_sPurpose( sPurpose ) +{ + pEnvUno = pEnvUno_; + pEnvRemote = pEnvRemote_; + + pEnvUno->acquire( pEnvUno ); + pEnvRemote->acquire( pEnvRemote ); + + aBase.mapInterface = func; + aBase.acquire = thisAcquire; + aBase.release = thisRelease; +} + +void RemoteMapping::thisFree( uno_Mapping * p ) +{ + delete ( RemoteMapping * ) p; +} + +RemoteMapping::~RemoteMapping( ) +{ + pEnvUno->release( pEnvUno ); + pEnvRemote->release( pEnvRemote ); +} + +void RemoteMapping::thisAcquire( uno_Mapping *pMap ) +{ + RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap ); + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + if( RemoteMapping::remoteToUno == pMap->mapInterface ) + { + uno_registerMapping( &pMap , + RemoteMapping::thisFree, + p->pEnvRemote , + p->pEnvUno , + p->m_sPurpose.pData ); + } + else + { + uno_registerMapping( &pMap , + RemoteMapping::thisFree, + p->pEnvUno , + p->pEnvRemote , + p->m_sPurpose.pData ); + } + + } +} + +void RemoteMapping::thisRelease( uno_Mapping *pMap ) +{ + RemoteMapping *p = SAL_REINTERPRET_CAST( RemoteMapping * , pMap ); + if (! osl_decrementInterlockedCount( &(p->m_nRef) )) + { + uno_revokeMapping( pMap ); + } +} + + +void RemoteMapping::remoteToUno( uno_Mapping *pMapping, + void **ppUnoI, + void *pRemoteI, + typelib_InterfaceTypeDescription *pTypeDescr ) +{ + remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping; + + OSL_ASSERT( ppUnoI && pTypeDescr ); + if (*ppUnoI) + { + ((uno_Interface *)*ppUnoI)->release( (uno_Interface *)*ppUnoI ); + *ppUnoI = 0; + } + + if (pRemoteI && pTypeDescr) + { + // get object id of interface to be wrapped + rtl_uString * pOid = 0; + pRemoteMapping->pEnvRemote->pExtEnv->getObjectIdentifier( + pRemoteMapping->pEnvRemote->pExtEnv, + &pOid, + pRemoteI ); + + OSL_ASSERT(pOid); + if( ! pOid ) + { + return; + } + + // try to get any known interface from target environment + pRemoteMapping->pEnvUno->pExtEnv->getRegisteredInterface( + pRemoteMapping->pEnvUno->pExtEnv, + ppUnoI, + pOid, + pTypeDescr); + + if ( ! *ppUnoI) // already existing interface + { + // try to publish a new proxy; proxy may be exchanged during registration + *ppUnoI = new Remote2UnoProxy( + ( remote_Interface * ) pRemoteI, + pOid, + pTypeDescr , + pRemoteMapping->pEnvUno, + pRemoteMapping->pEnvRemote); + + pRemoteMapping->pEnvUno->pExtEnv->registerProxyInterface( + pRemoteMapping->pEnvUno->pExtEnv, + ppUnoI, + Remote2UnoProxy::thisFree, + pOid, + pTypeDescr ); + + OSL_ASSERT( *ppUnoI ); + } + rtl_uString_release( pOid ); + } +} + + +void RemoteMapping::unoToRemote( uno_Mapping *pMapping, + void **ppRemoteI, + void *pUnoI, + typelib_InterfaceTypeDescription *pTypeDescr ) +{ + remote_Mapping *pRemoteMapping = ( remote_Mapping * ) pMapping; + OSL_ASSERT( ppRemoteI && pTypeDescr ); + if (*ppRemoteI) + { + ((remote_Interface *)*ppRemoteI)->release( (remote_Interface *)*ppRemoteI); + *ppRemoteI = 0; + } + if (pUnoI && pTypeDescr) + { + // get object id of interface to be wrapped + rtl_uString * pOid = 0; + pRemoteMapping->pEnvUno->pExtEnv->getObjectIdentifier( + pRemoteMapping->pEnvUno->pExtEnv, + &pOid, + pUnoI ); + + OSL_ASSERT( pOid ); + if( ! pOid ) + { + return; + } + + pRemoteMapping->pEnvRemote->pExtEnv->getRegisteredInterface( + pRemoteMapping->pEnvRemote->pExtEnv, + (void**)ppRemoteI, + pOid, + pTypeDescr ); + + if( !*ppRemoteI ) + { + // try to publish a new proxy; + *ppRemoteI = new Uno2RemoteStub( + ( uno_Interface * ) pUnoI, + pOid, + pTypeDescr, + pRemoteMapping->pEnvUno, + pRemoteMapping->pEnvRemote ); + + // note : ppRemoteI may change during registration + pRemoteMapping->pEnvRemote->pExtEnv->registerProxyInterface( + pRemoteMapping->pEnvRemote->pExtEnv, + (void**) ppRemoteI, + Uno2RemoteStub::thisFree, + pOid, + pTypeDescr ); + } + + rtl_uString_release( pOid ); + } +} + +} diff --git a/bridges/source/remote/static/proxy.cxx b/bridges/source/remote/static/proxy.cxx new file mode 100644 index 000000000000..3b488b7c2b27 --- /dev/null +++ b/bridges/source/remote/static/proxy.cxx @@ -0,0 +1,372 @@ +/************************************************************************* + * + * $RCSfile: proxy.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <assert.h> +#ifdef SOLARIS +#include <alloca.h> +#else +#include <malloc.h> +#endif + +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/context.h> + +#include <uno/data.h> +#include <uno/mapping.hxx> +#include <uno/environment.h> + +#include <com/sun/star/uno/Any.hxx> + +#include <bridges/remote/bridgeimpl.hxx> + +#include "remote_types.hxx" + +#ifdef DEBUG +#include <bridges/remote/counter.hxx> +static MyCounter thisCounter( "DEBUG : Remote2UnoProxy"); +#endif + +using namespace ::bridges_remote; +using namespace ::com::sun::star::uno; + +namespace bridges_remote { + +Remote2UnoProxy::Remote2UnoProxy( remote_Interface *pRemoteI, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvUno, + uno_Environment *pEnvRemote ) : + m_pType( pType ), + m_pRemoteI( pRemoteI ), + m_pEnvUno( pEnvUno ), + m_pEnvRemote( pEnvRemote ), + m_sOid( pOid ), + m_nRef( 1 ), + m_mapRemote2Uno( pEnvRemote, pEnvUno ), + m_mapUno2Remote( pEnvUno , pEnvRemote ) +{ + typelib_typedescription_acquire( (typelib_TypeDescription * ) m_pType ); + m_pEnvUno->acquire( m_pEnvUno ); + m_pEnvRemote->acquire( m_pEnvRemote ); + + acquire = thisAcquire; + release = thisRelease; + pDispatcher = ( uno_DispatchMethod ) thisDispatch; + + m_pEnvRemote->pExtEnv->registerInterface( + m_pEnvRemote->pExtEnv, + (void**)&m_pRemoteI, + m_sOid.pData, + m_pType ); + m_pRemoteI->acquire( m_pRemoteI ); + +#ifdef DEBUG + thisCounter.acquire(); +#endif +} + +Remote2UnoProxy::~Remote2UnoProxy() +{ + // revoke external ref (oid) + m_pEnvRemote->pExtEnv->revokeInterface( m_pEnvRemote->pExtEnv , m_pRemoteI ); + + typelib_typedescription_release( (typelib_TypeDescription * )m_pType ); + m_pRemoteI->release( m_pRemoteI ); + m_pEnvUno->release( m_pEnvUno ); + m_pEnvRemote->release( m_pEnvRemote ); +#ifdef DEBUG + thisCounter.release(); +#endif +} + +void Remote2UnoProxy::thisFree( uno_ExtEnvironment *pEnvUno , void *pThis ) +{ + delete (Remote2UnoProxy*) pThis; +} + +void Remote2UnoProxy::thisAcquire( uno_Interface *pThis ) +{ + Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis; + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + p->m_pEnvUno->pExtEnv->registerProxyInterface( + p->m_pEnvUno->pExtEnv, + (void**)&pThis, + Remote2UnoProxy::thisFree, + p->m_sOid.pData, + p->m_pType ); + assert( (uno_Interface *)p == pThis ); + } +} + +void Remote2UnoProxy::thisRelease( uno_Interface *pThis ) +{ + Remote2UnoProxy *p = ( Remote2UnoProxy * ) pThis; + if ( 0 == osl_decrementInterlockedCount( &(p->m_nRef) )) + { + p->m_pEnvUno->pExtEnv->revokeInterface( p->m_pEnvUno->pExtEnv, p ); + } +} + +void SAL_CALL remote_release( void *pRemoteI ) +{ + ((remote_Interface * )pRemoteI)->release( (remote_Interface * ) pRemoteI ); +} + +void Remote2UnoProxy::thisDispatch( + uno_Interface * pUnoI, + typelib_TypeDescription * pType, + void * pReturn, + void * ppArgs[], + uno_Any ** ppException ) +{ + Remote2UnoProxy *p = ( Remote2UnoProxy * ) pUnoI; + RemoteThreadCounter counter( p->m_pEnvRemote ); + + typelib_InterfaceMethodTypeDescription *pMethodType = 0; + typelib_InterfaceAttributeTypeDescription *pAttributeType = 0; + typelib_TypeDescription *pReturnType = 0; + typelib_TypeDescription **ppArgType = 0; + sal_Int32 nArgCount = 0; + sal_Bool *pbIsIn = 0; + sal_Bool *pbIsOut = 0; + sal_Bool *pbConversionNeeded = 0; + sal_Bool bConversionNeededForReturn = 0; + + //-------------------------------- + // Collect all needed types ! + //-------------------------------- + if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass ) + { + pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType; + if( pReturn ) + { + TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + } + else + { + nArgCount = 1; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) ); + pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) ); + + pbIsIn[0] = sal_True; + pbIsOut[0] = sal_False; + ppArgType[0] = 0; + TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef ); + pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] ); + + } + } + if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass ) + { + pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType; + TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + nArgCount = pMethodType->nParams; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount ); + pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbConversionNeeded = ( sal_Bool *) alloca( sizeof( sal_Bool ) * nArgCount ); + sal_Int32 i; + for( i = 0 ; i < nArgCount ; i ++ ) + { + ppArgType[i] = 0; + TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef ); + pbIsIn[i] = pMethodType->pParams[i].bIn; + pbIsOut[i] = pMethodType->pParams[i].bOut; + pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] ); + } + } + + void *pRemoteReturn = 0; + if( pReturnType ) + { + if( bConversionNeededForReturn ) + { + pRemoteReturn = alloca( pReturnType->nSize ); + } + else + { + pRemoteReturn = pReturn; + } + } + + void ** ppRemoteArgs = 0; + if( nArgCount ) + { + ppRemoteArgs = (void**) alloca( sizeof( void * ) * nArgCount ); + } + + sal_Int32 i; + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] ) + { + ppRemoteArgs[i] = alloca( ppArgType[i]->nSize ); + + if( pbIsIn[i] ) { + uno_copyAndConvertData( + ppRemoteArgs[i], + ppArgs[i], + ppArgType[i], + p->m_mapUno2Remote.get() ); + } + } + else + { + ppRemoteArgs[i] = ppArgs[i]; + } + } + + uno_Any any; + uno_Any *pAny = &any; + + p->m_pRemoteI->pDispatcher( p->m_pRemoteI, + pType, + pRemoteReturn, + ppRemoteArgs, + &pAny ); + + if( ! pAny ) + { + if( pReturn && bConversionNeededForReturn ) + { + uno_copyAndConvertData( + pReturn , + pRemoteReturn, + pReturnType, + p->m_mapRemote2Uno.get() ); + uno_destructData( pRemoteReturn , pReturnType , remote_release ); + } + + sal_Int32 i; + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] ) + { + if( pbIsIn[i] ) { + if( pbIsOut[i] ) { + uno_destructData( ppArgs[i] , + ppArgType[i] , + 0 ); + uno_copyAndConvertData( ppArgs[i] , + ppRemoteArgs[i], + ppArgType[i], + p->m_mapRemote2Uno.get() ); + } + } + else // pure out + { + uno_copyAndConvertData( ppArgs[i] , + ppRemoteArgs[i], + ppArgType[i], + p->m_mapRemote2Uno.get() ); + } + uno_destructData( ppRemoteArgs[i], + ppArgType[i], + remote_release ); + } + } + *ppException = 0; + } + else + { + // ----------------------- + // an exception occured + // ----------------------- + typelib_TypeDescription *pAnyType = 0; + getCppuType( (::com::sun::star::uno::Any*) 0 ).getDescription( &pAnyType ); + uno_copyAndConvertData( *ppException , + pAny , + pAnyType, + p->m_mapRemote2Uno.get() ); + uno_destructData( pAny , pAnyType , remote_release ); + typelib_typedescription_release( pAnyType ); + + // destruct remote in parameters ( out parameters have not been constructed ) + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] && pbIsIn[i] ) + { + uno_destructData( ppRemoteArgs[i], + ppArgType[i], + remote_release ); + } + } + } + + //-------------------------- + // release all acquired types + //-------------------------- + if( pReturnType ) + { + TYPELIB_DANGER_RELEASE( pReturnType ); + } + for( i = 0 ; i < nArgCount ; i ++ ) + { + TYPELIB_DANGER_RELEASE( ppArgType[ i] ); + } + +} + +} // end namespace bridge_remote diff --git a/bridges/source/remote/static/remote.cxx b/bridges/source/remote/static/remote.cxx new file mode 100644 index 000000000000..948d9a631ae6 --- /dev/null +++ b/bridges/source/remote/static/remote.cxx @@ -0,0 +1,172 @@ +/************************************************************************* + * + * $RCSfile: remote.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <assert.h> + +#include <bridges/remote/remote.hxx> +#include <bridges/remote/counter.hxx> + +#ifdef DEBUG +static MyCounter thisCounter( "DEBUG : Remote2RemoteStub"); +#endif + +namespace bridges_remote { + +Remote2RemoteStub::Remote2RemoteStub( rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvRemote, + requestClientSideDispatcher dispatch ) : + m_pType( (typelib_InterfaceTypeDescription * ) pType ), + m_pEnvRemote( pEnvRemote ), + m_sOid( pOid ), + m_nRef( 1 ), + m_dispatch( dispatch ) +{ + typelib_typedescription_acquire( ( typelib_TypeDescription * ) m_pType ); + m_pEnvRemote->acquire( m_pEnvRemote ); + + acquire = thisAcquire; + release = thisRelease; + pDispatcher = thisDispatch; +#ifdef DEBUG + thisCounter.acquire(); +#endif +} + +Remote2RemoteStub::~Remote2RemoteStub() +{ + + // send a release via the connection ! + releaseRemote(); + + typelib_typedescription_release( (typelib_TypeDescription * ) m_pType ); + m_pEnvRemote->release( m_pEnvRemote ); +#ifdef DEBUG + thisCounter.release(); +#endif +} + + +void Remote2RemoteStub::thisFree( uno_ExtEnvironment *pEnvUno , void *pThis ) +{ + delete (Remote2RemoteStub *) pThis; +} +void Remote2RemoteStub::releaseRemote() +{ + uno_Any any; + uno_Any *pAny = &any; + + typelib_TypeDescription *pReleaseMethod = 0; + typelib_typedescriptionreference_getDescription( + &pReleaseMethod , + m_pType->ppAllMembers[REMOTE_RELEASE_METHOD_INDEX] ); + thisDispatch( this, + pReleaseMethod, + 0, + 0, + &pAny ); + + typelib_typedescription_release( pReleaseMethod ); +} + +void Remote2RemoteStub::thisAcquire( remote_Interface *pThis ) +{ + Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis; + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + p->m_pEnvRemote->pExtEnv->registerProxyInterface( + p->m_pEnvRemote->pExtEnv, + (void**)&pThis, + Remote2RemoteStub::thisFree, + p->m_sOid.pData, + p->m_pType ); + assert( (remote_Interface *)p == pThis ); + } +} + +void Remote2RemoteStub::thisRelease( remote_Interface *pThis ) +{ + Remote2RemoteStub *p = ( Remote2RemoteStub * ) pThis; + if (! osl_decrementInterlockedCount( &(p->m_nRef) )) + { + p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis ); + + } +} + +void Remote2RemoteStub::thisDispatch( + remote_Interface * pRemoteI, + typelib_TypeDescription * pMemberType, + void * pReturn, + void * pArgs[], + uno_Any ** ppException ) +{ + Remote2RemoteStub *pThis = ( Remote2RemoteStub * ) pRemoteI; + + pThis->m_dispatch( pThis->m_pEnvRemote, + pMemberType, + pThis->m_sOid.pData, + pThis->m_pType, + pReturn, + pArgs, + ppException ); +} + +} // end namespace bridges_remote diff --git a/bridges/source/remote/static/remote_types.cxx b/bridges/source/remote/static/remote_types.cxx new file mode 100644 index 000000000000..baa684037551 --- /dev/null +++ b/bridges/source/remote/static/remote_types.cxx @@ -0,0 +1,123 @@ +/************************************************************************* + * + * $RCSfile: remote_types.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 "remote_types.hxx" + +namespace bridges_remote { + +sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr ) +{ + switch (pTypeDescr->eTypeClass) + { + case typelib_TypeClass_SEQUENCE: + { + switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass) + { + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, ((typelib_IndirectTypeDescription *)pTypeDescr)->pType ); + sal_Bool bRel = remote_relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + return bRel; + } + + } + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + // ...optimized... to avoid getDescription() calls! + typelib_CompoundTypeDescription * pComp = (typelib_CompoundTypeDescription *)pTypeDescr; + typelib_TypeDescriptionReference ** pTypes = pComp->ppTypeRefs; + for ( sal_Int32 nPos = pComp->nMembers; nPos--; ) + { + switch (pTypes[nPos]->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return sal_True; + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_TypeDescription * pTD = 0; + TYPELIB_DANGER_GET( &pTD, pTypes[nPos] ); + sal_Bool bRel = remote_relatesToInterface( pTD ); + TYPELIB_DANGER_RELEASE( pTD ); + if (bRel) + return sal_True; + } + } + } + if (pComp->pBaseTypeDescription) + return remote_relatesToInterface( (typelib_TypeDescription *)pComp->pBaseTypeDescription ); + break; + } + default: + OSL_ASSERT( 0 ); + } + return sal_False; +} + +} diff --git a/bridges/source/remote/static/remote_types.hxx b/bridges/source/remote/static/remote_types.hxx new file mode 100644 index 000000000000..745ec6f0e349 --- /dev/null +++ b/bridges/source/remote/static/remote_types.hxx @@ -0,0 +1,134 @@ +/************************************************************************* + * + * $RCSfile: remote_types.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _BRIDGES_REMOTE_TYPES_HXX_ +#define _BRIDGES_REMOTE_TYPES_HXX_ + +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +#ifndef _SAL_TYPES_H_ +#include <sal/types.h> +#endif +#ifndef _TYPELIB_TYPEDESCRIPTION_H_ +#include <typelib/typedescription.h> +#endif + +namespace bridges_remote +{ + +inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription *pTypeDescr ); +sal_Bool SAL_CALL remote_relatesToInterface2( typelib_TypeDescription * pTypeDescr ); + + +/** Determines whether given type might relate or relates to an interface, + i.e. values of this type are interface or may contain interface(s).<br> + @param pTypeDescr type description of type + @return true if type might relate to an interface, false otherwise +*/ +inline sal_Bool SAL_CALL remote_relatesToInterface( typelib_TypeDescription * pTypeDescr ) +{ + switch (pTypeDescr->eTypeClass) + { + case typelib_TypeClass_SEQUENCE: + { + switch (((typelib_IndirectTypeDescription *)pTypeDescr)->pType->eTypeClass) + { + case typelib_TypeClass_INTERFACE: + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + return sal_True; + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + return remote_relatesToInterface2( pTypeDescr ); + } + } + return sal_False; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + return remote_relatesToInterface2( pTypeDescr ); + } + case typelib_TypeClass_UNION: // might relate to interface + case typelib_TypeClass_ANY: // might relate to interface + case typelib_TypeClass_INTERFACE: + return sal_True; + } + return sal_False; +} + +/** Determines whether given type is a cpp simple type, e.g. int, enum.<br> + @param pTypeDescr type description of type + @return true if type is a cpp simple type, false otherwise +*/ +inline sal_Bool SAL_CALL remote_isSimpleType( typelib_TypeDescription * pTypeDescr ) +{ + return (pTypeDescr->eTypeClass <= typelib_TypeClass_ENUM && + pTypeDescr->eTypeClass != typelib_TypeClass_STRING && + pTypeDescr->eTypeClass != typelib_TypeClass_ANY && + pTypeDescr->eTypeClass != typelib_TypeClass_TYPE); +} + +} +#endif diff --git a/bridges/source/remote/static/stub.cxx b/bridges/source/remote/static/stub.cxx new file mode 100644 index 000000000000..aec8a39140fe --- /dev/null +++ b/bridges/source/remote/static/stub.cxx @@ -0,0 +1,370 @@ +/************************************************************************* + * + * $RCSfile: stub.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifdef SOLARIS +#include <alloca.h> +#else +#include <malloc.h> +#endif + +#include <osl/diagnose.h> + +#include <uno/data.h> +#include <uno/mapping.hxx> + +#include <bridges/remote/stub.hxx> +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/context.h> +#include <bridges/remote/bridgeimpl.hxx> + +#include "remote_types.hxx" + +#ifdef DEBUG +#include <bridges/remote/counter.hxx> +static MyCounter thisCounter( "DEBUG : Uno2RemoteStub"); +#endif + +using namespace ::com::sun::star::uno; + +namespace bridges_remote { + +Uno2RemoteStub::Uno2RemoteStub( uno_Interface *pUnoI, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pType, + uno_Environment *pEnvUno, + uno_Environment *pEnvRemote ) : + m_pType( pType ), + m_pUnoI( pUnoI ), + m_pEnvUno( pEnvUno ), + m_pEnvRemote( pEnvRemote ), + m_sOid( pOid ), + m_nRef( 1 ), + m_mapRemote2Uno( pEnvRemote, pEnvUno ), + m_mapUno2Remote( pEnvUno, pEnvRemote ) +{ + typelib_typedescription_acquire( (typelib_TypeDescription * )m_pType ); + m_pEnvUno->acquire( m_pEnvUno ); + m_pEnvRemote->acquire( m_pEnvRemote ); + + acquire = thisAcquire; + release = thisRelease; + pDispatcher = thisDispatch; + + m_pEnvUno->pExtEnv->registerInterface( m_pEnvUno->pExtEnv, + (void **)&m_pUnoI, + m_sOid.pData, + m_pType ); + m_pUnoI->acquire( m_pUnoI ); +#ifdef DEBUG + thisCounter.acquire(); +#endif +} + +Uno2RemoteStub::~Uno2RemoteStub() +{ + m_pEnvUno->pExtEnv->revokeInterface( m_pEnvUno->pExtEnv , m_pUnoI ); + + typelib_typedescription_release( (typelib_TypeDescription * )m_pType ); + m_pUnoI->release( m_pUnoI ); + m_pEnvUno->release( m_pEnvUno ); + m_pEnvRemote->release( m_pEnvRemote ); +#ifdef DEBUG + thisCounter.release(); +#endif +} + + +void Uno2RemoteStub::thisFree( uno_ExtEnvironment *pEnvRemote, void *pThis ) +{ + delete ( Uno2RemoteStub * ) pThis; +} + +void Uno2RemoteStub::thisAcquire( remote_Interface *pThis ) +{ + Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis; + if( 1 == osl_incrementInterlockedCount( &(p->m_nRef) ) ) + { + + p->m_pEnvRemote->pExtEnv->registerProxyInterface( + p->m_pEnvRemote->pExtEnv, + (void**)&pThis, + Uno2RemoteStub::thisFree, + p->m_sOid.pData, + p->m_pType ); + + OSL_ASSERT( (remote_Interface*) p == pThis ); + } +} + +void Uno2RemoteStub::thisRelease( remote_Interface *pThis ) +{ + Uno2RemoteStub *p = ( Uno2RemoteStub * ) pThis; + if (! osl_decrementInterlockedCount( &(p->m_nRef) )) + { + p->m_pEnvRemote->pExtEnv->revokeInterface( p->m_pEnvRemote->pExtEnv, pThis ); + } +} + +void Uno2RemoteStub::thisDispatch( + remote_Interface * pRemoteI, + typelib_TypeDescription * pType, + void * pReturn, + void * ppArgs[], + uno_Any ** ppException ) +{ + Uno2RemoteStub *p = ( Uno2RemoteStub * ) pRemoteI; + + RemoteThreadCounter counter( p->m_pEnvRemote ); + + typelib_InterfaceMethodTypeDescription *pMethodType = 0; + typelib_InterfaceAttributeTypeDescription *pAttributeType = 0; + typelib_TypeDescription *pReturnType = 0; + typelib_TypeDescription **ppArgType = 0; + sal_Int32 nArgCount = 0; + sal_Bool *pbIsIn = 0; + sal_Bool *pbIsOut = 0; + sal_Bool bConversionNeededForReturn = sal_False; + sal_Bool *pbConversionNeeded = 0; + + sal_Int32 i; + //-------------------------------- + // Collect all needed types ! + //-------------------------------- + if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pType->eTypeClass ) + { + pAttributeType = ( typelib_InterfaceAttributeTypeDescription * ) pType; + if( pReturn ) + { + TYPELIB_DANGER_GET( &pReturnType , pAttributeType->pAttributeTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + } + else + { + nArgCount = 1; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) ); + pbIsIn = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbIsOut = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) ); + pbIsIn[0] = sal_True; + pbIsOut[0] = sal_False; + ppArgType[0] = 0; + TYPELIB_DANGER_GET( &( ppArgType[0] ) , pAttributeType->pAttributeTypeRef ); + pbConversionNeeded[0] = remote_relatesToInterface( ppArgType[0] ); + } + } + if( typelib_TypeClass_INTERFACE_METHOD == pType->eTypeClass ) + { + pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pType; + TYPELIB_DANGER_GET( &pReturnType , pMethodType->pReturnTypeRef ); + bConversionNeededForReturn = remote_relatesToInterface( pReturnType ); + nArgCount = pMethodType->nParams; + ppArgType = (typelib_TypeDescription **) alloca( sizeof( void * ) * nArgCount ); + pbIsIn = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbIsOut = (sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + pbConversionNeeded = ( sal_Bool * ) alloca( sizeof( sal_Bool ) * nArgCount ); + + for( i = 0 ; i < nArgCount ; i ++ ) + { + ppArgType[i] = 0; + TYPELIB_DANGER_GET( & (ppArgType[i]) , pMethodType->pParams[i].pTypeRef ); + pbIsIn[i] = pMethodType->pParams[i].bIn; + pbIsOut[i] = pMethodType->pParams[i].bOut; + pbConversionNeeded[i] = remote_relatesToInterface( ppArgType[i] ); + } + } + + // create Mapping + + void *pUnoReturn = 0; + void **ppUnoArgs = 0; + + if( pReturnType ) + { + if( bConversionNeededForReturn ) + { + pUnoReturn = alloca( pReturnType->nSize ); + } + else + { + pUnoReturn = pReturn; + } + } + + ppUnoArgs = (void **) alloca( nArgCount * sizeof( void * ) ); + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] ) + { + ppUnoArgs[i] = alloca( ppArgType[i]->nSize ); + if( pbIsIn[i] ) + { + uno_copyAndConvertData( + ppUnoArgs[i], + ppArgs[i], + ppArgType[i], + p->m_mapRemote2Uno.get() + ); + } + } + else + { + ppUnoArgs[i] = ppArgs[i]; + } + } + + // do the call + uno_Any any; + uno_Any *pAny = &any; + + p->m_pUnoI->pDispatcher( p->m_pUnoI, + pType, + pUnoReturn, + ppUnoArgs, + &pAny); + + if( ! pAny ) + { + // ------------------ + // No Exception + // ------------------ + + // Map return value + if( pReturnType && bConversionNeededForReturn ) + { + uno_copyAndConvertData( + pReturn , + pUnoReturn, + pReturnType, + p->m_mapUno2Remote.get() ); + uno_destructData( pUnoReturn , pReturnType, 0 ); + } + + // map arguments + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] ) + { + if( pbIsIn[i] ) { + if( pbIsOut[i] ) { + uno_destructData( + ppArgs[i] , + ppArgType[i] , + remote_release ); + uno_copyAndConvertData( ppArgs[i] , + ppUnoArgs[i], + ppArgType[i], + p->m_mapUno2Remote.get() ); + } + } + else // pure out + { + uno_copyAndConvertData( ppArgs[i] , + ppUnoArgs[i], + ppArgType[i], + p->m_mapUno2Remote.get() ); + } + uno_destructData( ppUnoArgs[i], + ppArgType[i], + 0 ); + } + } + *ppException = 0; + } + else + { + // ----------------------- + // an exception occured + // ----------------------- + typelib_TypeDescription *pAnyType = 0; + getCppuType( (Any*) 0 ).getDescription( &pAnyType ); + uno_copyAndConvertData( *ppException , + pAny , + pAnyType, + p->m_mapUno2Remote.get() ); + uno_destructData( pAny , pAnyType , 0 ); + typelib_typedescription_release( pAnyType ); + + // destruct uno in parameters ( out parameters have not been constructed ) + for( i = 0 ; i < nArgCount ; i ++ ) + { + if( pbConversionNeeded[i] && pbIsIn[i] ) + { + uno_destructData( ppUnoArgs[i], + ppArgType[i], + 0 ); + } + } + } + + //-------------------------- + // release all acquired types + //-------------------------- + if( pReturnType ) + { + TYPELIB_DANGER_RELEASE( pReturnType ); + } + for( i = 0 ; i < nArgCount ; i ++ ) + { + TYPELIB_DANGER_RELEASE( ppArgType[ i] ); + } +} + + +} // end namespace bridges_remote diff --git a/bridges/source/remote/urp/makefile.mk b/bridges/source/remote/urp/makefile.mk new file mode 100644 index 000000000000..efad07ea82d9 --- /dev/null +++ b/bridges/source/remote/urp/makefile.mk @@ -0,0 +1,130 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ +# +# 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=urp_uno +ENABLE_EXCEPTIONS=TRUE +USE_DEFFILE=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# ------------------------------------------------------------------ + +#CPPUMAKERFLAGS += -C +UNOUCRDEP=$(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb + +# output directory (one dir for each project) +UNOUCROUT=$(OUT)$/inc + +# adding to inludepath +INCPRE+=$(UNOUCROUT) + +UNOTYPES= \ + com.sun.star.uno.XInterface \ + com.sun.star.uno.TypeClass + + +SLOFILES= \ + $(SLO)$/urp_environment.obj \ + $(SLO)$/urp_marshal.obj \ + $(SLO)$/urp_unmarshal.obj \ + $(SLO)$/urp_dispatch.obj \ + $(SLO)$/urp_job.obj \ + $(SLO)$/urp_reader.obj \ + $(SLO)$/urp_writer.obj \ + $(SLO)$/urp_log.obj \ + $(SLO)$/urp_bridgeimpl.obj + +SHL1TARGET= $(TARGET) + +SHL1STDLIBS=\ + $(SALLIB)\ + $(VOSLIB)\ + $(CPPULIB) + +SHL1LIBS=\ + $(SLB)$/$(TARGET).lib \ + $(SLB)$/bridges_remote_static.lib + + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +$(MISC)$/$(SHL1TARGET).def: makefile.mk + @echo ------------------------------ + @echo Making: $@ + @echo LIBRARY $(SHL1TARGET) >$@ + @echo DESCRIPTION 'URP to UNO binding' >>$@ + @echo DATA READ WRITE NONSHARED >>$@ + @echo EXPORTS >>$@ + @echo uno_initEnvironment @3 >>$@ + @echo uno_ext_getMapping @4 >>$@ + diff --git a/bridges/source/remote/urp/urp_bridgeimpl.cxx b/bridges/source/remote/urp/urp_bridgeimpl.cxx new file mode 100644 index 000000000000..730a302cdfa4 --- /dev/null +++ b/bridges/source/remote/urp/urp_bridgeimpl.cxx @@ -0,0 +1,92 @@ +/************************************************************************* + * + * $RCSfile: urp_bridgeimpl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <bridges/remote/helper.hxx> + +#include "urp_bridgeimpl.hxx" + +using namespace ::rtl; +using namespace ::com::sun::star::uno; +namespace bridges_urp +{ + +/*********** + * urp_BridgeImpl + ***********/ +urp_BridgeImpl::urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize ) : + m_oidCacheOut( nCacheSize ), + m_tidCacheOut( nCacheSize ), + m_typeCacheOut( nCacheSize ), + m_nCacheSize( nCacheSize ), + m_blockMarshaler( this , nInitialMarshalerSize , ::bridges_remote::remote_retrieveOidFromProxy) +{ + m_pOidIn = new OUString[ nCacheSize ]; + m_pTidIn = new ByteSequence[ nCacheSize ]; + m_pTypeIn = new Type[ nCacheSize ]; + m_nRemoteThreads = 0; +} + +urp_BridgeImpl::~urp_BridgeImpl() +{ + delete [] m_pOidIn; + delete [] m_pTidIn; + delete [] m_pTypeIn; +} +} diff --git a/bridges/source/remote/urp/urp_bridgeimpl.hxx b/bridges/source/remote/urp/urp_bridgeimpl.hxx new file mode 100644 index 000000000000..c141c06c0128 --- /dev/null +++ b/bridges/source/remote/urp/urp_bridgeimpl.hxx @@ -0,0 +1,142 @@ +/************************************************************************* + * + * $RCSfile: urp_bridgeimpl.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _URP_BRIDGEIMPL_HXX_ +#define _URP_BRIDGEIMPL_HXX_ + +#include <stdio.h> +#include <osl/mutex.hxx> +#include <osl/conditn.hxx> + +#include <rtl/ustring.hxx> +#include <rtl/byteseq.hxx> + +#include <bridges/remote/bridgeimpl.hxx> + +#include "urp_cache.hxx" +#include "urp_marshal_decl.hxx" +#include "urp_replycontainer.hxx" + + +namespace bridges_urp +{ + +struct equalOUString +{ + sal_Int32 operator() ( const ::rtl::OUString &s1, const ::rtl::OUString &s2 ) const + { + return s1 == s2; + } +}; + +struct equalType +{ + sal_Int32 operator() ( const ::com::sun::star::uno::Type &t1, + const ::com::sun::star::uno::Type &t2 ) const + { + return t1 == t2; + } +}; + +class OWriterThread; +class OReaderThread; + +struct urp_BridgeImpl : + public remote_BridgeImpl +{ + urp_BridgeImpl( sal_Int32 nCacheSize , sal_uInt32 nInitialMarshalerSize ); + ~urp_BridgeImpl(); + + ::osl::Mutex m_marshalingMutex; + ::osl::Mutex m_disposingMutex; + Marshal m_blockMarshaler; + + // Caches for vars, that go from local process to the remote process + Cache < ::rtl::OUString , equalOUString > m_oidCacheOut; + Cache < ::rtl::ByteSequence , EqualThreadId > m_tidCacheOut; + Cache < ::com::sun::star::uno::Type , equalType > m_typeCacheOut; + + ::com::sun::star::uno::Type m_lastOutType; + ::rtl::ByteSequence m_lastOutTid; + ::rtl::OUString m_lastOutOid; + + // Caches for vars, that come from the remote process to the local process + sal_Int32 m_nCacheSize; + ::rtl::OUString *m_pOidIn; + ::rtl::ByteSequence *m_pTidIn; + ::com::sun::star::uno::Type *m_pTypeIn; + + ::com::sun::star::uno::Type m_lastInType; + ::rtl::ByteSequence m_lastInTid; + ::rtl::OUString m_lastInOid; + + sal_Int32 m_nTimeoutMUSEC; + sal_Int32 m_nFlushBlockSize; + + urp_ClientJobContainer m_clientJobContainer; + + OWriterThread *m_pWriter; + OReaderThread *m_pReader; + FILE *m_pLogFile; + ::osl::Condition m_cndWaitForThreads; +}; + +} +#endif diff --git a/bridges/source/remote/urp/urp_cache.h b/bridges/source/remote/urp/urp_cache.h new file mode 100644 index 000000000000..e60d70f8d3fa --- /dev/null +++ b/bridges/source/remote/urp/urp_cache.h @@ -0,0 +1,86 @@ +/************************************************************************* + * + * $RCSfile: urp_cache.h,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ + + +namespace bridges_urp +{ + template < class t , class tequals > + class Cache + { + public: + inline Cache ( sal_uInt16 nMaxEntries ); + inline ~Cache(); + + // puts the value t into the cache. Returns then entry, + // that is used for this value. + inline sal_uInt16 put( const t & ); + + // lookup, if there is an entry for this value + // returns 0xffff, when value cannot be found in the list + inline sal_uInt16 seek( const t & ); + + private: + t *m_pCache; + ::std::list< sal_uInt16 > m_lstLeastRecentlyUsed; + sal_uInt16 m_nMaxEntries; + sal_uInt16 m_nEntries; + }; +} diff --git a/bridges/source/remote/urp/urp_cache.hxx b/bridges/source/remote/urp/urp_cache.hxx new file mode 100644 index 000000000000..c399faa1ca5e --- /dev/null +++ b/bridges/source/remote/urp/urp_cache.hxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * $RCSfile: urp_cache.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <list> + +#include <rtl/ustring.hxx> + +#include "urp_threadid.hxx" + +#include "urp_cache.h" + +namespace bridges_urp +{ + + template < class t , class tequals > + inline Cache< t , tequals >::Cache( sal_uInt16 nMaxEntries ) : + m_pCache( new t[nMaxEntries] ), + m_nMaxEntries( nMaxEntries ), + m_nEntries( 0 ) + { + + } + + template < class t , class tequals > + inline Cache< t , tequals >::~Cache( ) + { + delete [] m_pCache; + } + + + template < class t , class tequals > + inline sal_uInt16 Cache< t , tequals >::put( const t & value ) + { + sal_uInt16 nEntry = 0xffff; + if( m_nEntries < m_nMaxEntries ) + { + // cache has still empty places + m_pCache[m_nEntries] = value; + nEntry = m_nEntries; + m_nEntries ++; + + // add it to the cache + m_lstLeastRecentlyUsed.push_front( nEntry ); + } + else + { + // cache is full, remove an element and insert the new one + nEntry = m_lstLeastRecentlyUsed.back(); + m_lstLeastRecentlyUsed.pop_back(); + m_lstLeastRecentlyUsed.push_front( nEntry ); + + m_pCache[nEntry] = value; + } + return nEntry; + } + + template < class t , class tequals > + inline sal_uInt16 Cache< t , tequals >::seek( const t & value ) + { + for( ::std::list< sal_uInt16 >::iterator ii = m_lstLeastRecentlyUsed.begin() ; + ii != m_lstLeastRecentlyUsed.end() ; + ++ ii ) + { + if( value == m_pCache[*ii] ) + { + sal_uInt16 nEntry = *ii; + m_lstLeastRecentlyUsed.erase( ii ); + m_lstLeastRecentlyUsed.push_front( nEntry ); + return nEntry; + } + } + return 0xffff; + } +} diff --git a/bridges/source/remote/urp/urp_dispatch.cxx b/bridges/source/remote/urp/urp_dispatch.cxx new file mode 100644 index 000000000000..1b492e0e6309 --- /dev/null +++ b/bridges/source/remote/urp/urp_dispatch.cxx @@ -0,0 +1,370 @@ +/************************************************************************* + * + * $RCSfile: urp_dispatch.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifdef SOLARIS +#include <alloca.h> +#else +#include <malloc.h> +#endif + +#include <osl/mutex.hxx> +#include <osl/diagnose.h> + +#include <rtl/alloc.h> +#include <rtl/ustrbuf.hxx> + +#include <vos/timer.hxx> + +#include <uno/mapping.hxx> +#include <uno/threadpool.h> + +#include <bridges/remote/remote.h> +#include <bridges/remote/stub.hxx> +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/remote.hxx> + +#include "urp_bridgeimpl.hxx" +#include "urp_marshal.hxx" +#include "urp_dispatch.hxx" +#include "urp_job.hxx" +#include "urp_writer.hxx" +#include "urp_log.hxx" + +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star::uno; + +namespace bridges_urp +{ + +void prepareRuntimeExceptionClientSide( uno_Any **ppException , const OUString &s) +{ + + // TODO : add string to runtimeexception + Type type = ::getCppuType( ( ::com::sun::star::uno::RuntimeException *) 0 ); + uno_type_any_construct( *ppException , 0 , type.getTypeLibType() , 0 ); +} + +void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote ) +{ + remote_Context *pContext = (remote_Context *) pEnvRemote->pContext; + urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl ); + + { + MutexGuard guard( pImpl->m_marshalingMutex ); + sal_uInt8 nBitfield = 0; + + // send immeadiatly + if( ! pImpl->m_blockMarshaler.empty() ) + { + pImpl->m_pWriter->touch( sal_True ); + } + + pImpl->m_pWriter->sendEmptyMessage(); + } +} + +void SAL_CALL urp_sendRequest( + uno_Environment *pEnvRemote, + typelib_TypeDescription * pMemberType, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pInterfaceType, + void *pReturn, + void *ppArgs[], + uno_Any **ppException + ) +{ + remote_Context *pContext = (remote_Context *) pEnvRemote->pContext; + urp_BridgeImpl *pImpl = (urp_BridgeImpl*) ( pContext->m_pBridgeImpl ); + + uno_threadpool_Handle *pThreadpoolHandle = 0; + sal_Bool bOneway = typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass ? + (( typelib_InterfaceMethodTypeDescription * ) pMemberType)->bOneWay : + sal_False; + sal_Bool bReleaseForTypeDescriptionNecessary = sal_False; + + // get thread id + sal_Sequence *pThreadId = 0; + uno_getIdOfCurrentThread( &pThreadId ); + ByteSequence aThreadId = ByteSequence( pThreadId , BYTESEQ_NOACQUIRE ); + + ClientJob clientJob = ClientJob( pEnvRemote, pImpl ); + { + MutexGuard guard( pImpl->m_marshalingMutex ); + + if( pImpl->m_bDisposed ) + { + prepareRuntimeExceptionClientSide( + ppException , OUString( RTL_CONSTASCII_USTRINGPARAM( "URP-Bridge: disposed" )) ); + return; + } + + clientJob.m_ppArgs = ppArgs; + clientJob.m_pReturn = pReturn; + clientJob.m_ppException = ppException; + + if( typelib_TypeClass_INTERFACE_METHOD == pMemberType->eTypeClass ) + { + clientJob.m_pMethodType = ( typelib_InterfaceMethodTypeDescription * ) pMemberType; + } + + if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->eTypeClass ) + { + clientJob.m_pAttributeType = + ( typelib_InterfaceAttributeTypeDescription * ) pMemberType; + } + + // calculate method index + sal_Int32 nMethodIndex = 0; + if( ! pInterfaceType->aBase.bComplete ) + { + // must be acquired because typedescription may be exchanged + typelib_typedescription_acquire((typelib_TypeDescription*) pInterfaceType ); + bReleaseForTypeDescriptionNecessary = sal_True; + typelib_typedescription_complete( (typelib_TypeDescription ** ) &pInterfaceType ); + } + nMethodIndex = pInterfaceType->pMapMemberIndexToFunctionIndex[ + ((typelib_InterfaceMemberTypeDescription*)pMemberType)->nPosition ]; + + if( clientJob.m_pAttributeType && clientJob.m_ppArgs ) + { + // setter + nMethodIndex ++; + } + + // build up the flag byte + sal_Bool bType = sal_False, bOid = sal_False, bTid = sal_False; + sal_uInt8 nFlags = 0; + if( pImpl->m_lastOutType.getTypeLibType() != pInterfaceType->aBase.pWeakRef && + ! typelib_typedescriptionreference_equals( + pImpl->m_lastOutType.getTypeLibType(), pInterfaceType->aBase.pWeakRef ) ) + { + //new type + nFlags = nFlags | HDRFLAG_NEWTYPE; + bType = sal_True; + } + if( pImpl->m_lastOutOid.pData != pOid && + rtl_ustr_compare_WithLength( pImpl->m_lastOutOid.pData->buffer, + pImpl->m_lastOutOid.pData->length, + pOid->buffer, + pOid->length ) ) + { + //new object id + nFlags = nFlags | HDRFLAG_NEWOID; + bOid = sal_True; + } + if( pImpl->m_lastOutTid.getHandle() != aThreadId.getHandle() && + !(pImpl->m_lastOutTid == aThreadId) ) + { + // new threadid + nFlags = nFlags | HDRFLAG_NEWTID; + bTid = sal_True; + } +#ifdef BRIDGES_URP_PROT + sal_Int32 nLogStart = pImpl->m_blockMarshaler.getPos(); +#endif + if( nFlags ) + { + // the flag byte is needed + request + nFlags = nFlags | HDRFLAG_LONG | HDRFLAG_REQUEST; // + if( nMethodIndex >= 0x100 ) + { + nFlags = nFlags | HDRFLAG_LONGMETHODID; + } + if( clientJob.m_pMethodType && clientJob.m_pMethodType->bOneWay ) + { + // oneway + nFlags = nFlags | HDRFLAG_ONEWAY; + } + pImpl->m_blockMarshaler.packInt8( &nFlags ); + + if( nFlags & HDRFLAG_LONGMETHODID ) + { + sal_uInt16 nMethod = (sal_uInt16 ) nMethodIndex; + pImpl->m_blockMarshaler.packInt16( &nMethod ); + } + else + { + sal_uInt8 nMethod = (sal_uInt8) nMethodIndex; + pImpl->m_blockMarshaler.packInt8( &nMethod ); + } + } + else + { + // no flag byte needed, simply marshal the method index + if( nMethodIndex >= 64 ) + { + sal_uInt16 nMethod = ( sal_uInt16 ) nMethodIndex; + nMethod = nMethod | 0x4000; + pImpl->m_blockMarshaler.packInt16( &nMethod ); + } + else + { + sal_uInt8 nMethod = (sal_uInt8 ) nMethodIndex; + pImpl->m_blockMarshaler.packInt8( &nMethod ); + } + } + + // marshal type,oid,tid + if( bType ) + { + pImpl->m_lastOutType = pInterfaceType->aBase.pWeakRef; + pImpl->m_blockMarshaler.packType( &(pImpl->m_lastOutType) ); + } + if( bOid ) + { + pImpl->m_lastOutOid = pOid; + pImpl->m_blockMarshaler.packOid( pImpl->m_lastOutOid ); + } + if( bTid ) + { + pImpl->m_lastOutTid = aThreadId; + pImpl->m_blockMarshaler.packTid( pImpl->m_lastOutTid ); + } + + + // marshal arguments ! +#ifdef BRIDGES_URP_PROT + sal_Int32 nLogHeader = pImpl->m_blockMarshaler.getPos(); +#endif + if( clientJob.m_pMethodType ) + { + sal_Int32 i; + for( i = 0 ; i < clientJob.m_pMethodType->nParams ; i ++ ) + { + if( clientJob.m_pMethodType->pParams[i].bIn ) + { + typelib_TypeDescription *pType = 0; + TYPELIB_DANGER_GET( &pType , clientJob.m_pMethodType->pParams[i].pTypeRef ); + pImpl->m_blockMarshaler.pack( ppArgs[i] , pType ); + TYPELIB_DANGER_RELEASE( pType ); + } + } + } + else if( clientJob.m_pAttributeType && clientJob.m_pReturn ) + { + // nothing to do ! + } + else if( clientJob.m_pAttributeType && clientJob.m_ppArgs ) + { + typelib_TypeDescription *pType = 0; + TYPELIB_DANGER_GET( &pType , clientJob.m_pAttributeType->pAttributeTypeRef ); + pImpl->m_blockMarshaler.pack( clientJob.m_ppArgs[0] , pType ); + TYPELIB_DANGER_RELEASE( pType ); + } + else + { + OSL_ASSERT( 0 ); + } + +#ifdef BRIDGES_URP_PROT + urp_logCall( pImpl, pImpl->m_blockMarshaler.getPos() - nLogStart, + pImpl->m_blockMarshaler.getPos() - nLogHeader, ! bOneway, + ((typelib_InterfaceMemberTypeDescription*)pMemberType)->pMemberName ); +#endif + + if( ! bOneway ) + { + pThreadpoolHandle = uno_threadpool_createHandle( (sal_Int64 ) pEnvRemote ); + pImpl->m_clientJobContainer.add( aThreadId , &clientJob ); + } + + //--------------------------- + // Inform the writer thread, that there is some work to do + //--------------------------- + pImpl->m_pWriter->touch( !bOneway ); + + // release the guard + } + + if(! bOneway) + { + //--------------------------- + // Wait for the reply + //--------------------------- + ClientJob * pData = 0; + uno_threadpool_enter( pThreadpoolHandle, (void **) &pData ); + + if( ! pData ) + { + OSL_VERIFY( &clientJob == + pImpl->m_clientJobContainer.remove( aThreadId ) ); + + prepareRuntimeExceptionClientSide( + ppException, OUString( RTL_CONSTASCII_USTRINGPARAM( "URP_Bridge : disposed" ) ) ); + } + } + else + { + //---------------- + // One way call + //---------------- + *ppException = 0; + } + + uno_releaseIdFromCurrentThread(); + + if( bReleaseForTypeDescriptionNecessary ) + typelib_typedescription_release( (typelib_TypeDescription *) pInterfaceType ); +} + +} + + diff --git a/bridges/source/remote/urp/urp_dispatch.hxx b/bridges/source/remote/urp/urp_dispatch.hxx new file mode 100644 index 000000000000..630f7c19ce69 --- /dev/null +++ b/bridges/source/remote/urp/urp_dispatch.hxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * $RCSfile: urp_dispatch.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <rtl/ustring.hxx> + +#include <typelib/typedescription.h> + +#include <uno/any2.h> + + +typedef struct _uno_Environment uno_Environment; +struct remote_Interface; + + + +namespace bridges_urp { + + const sal_uInt8 HDRFLAG_LONG = 0x80; + const sal_uInt8 HDRFLAG_REQUEST = 0x40; + const sal_uInt8 HDRFLAG_EXCEPTIONOCCURED = 0x20; + const sal_uInt8 HDRFLAG_NEWTYPE = 0x20; + const sal_uInt8 HDRFLAG_NEWOID = 0x10; + const sal_uInt8 HDRFLAG_NEWTID = 0x08; + const sal_uInt8 HDRFLAG_LONGMETHODID = 0x04; + const sal_uInt8 HDRFLAG_ONEWAY = 0x02; + + void SAL_CALL urp_sendCloseConnection( uno_Environment *pEnvRemote ); + + void SAL_CALL urp_sendRequest( + uno_Environment *pEnvRemote, + typelib_TypeDescription * pMemberType, + rtl_uString *pOid, + typelib_InterfaceTypeDescription *pInterfaceType, + void *pReturn, + void *ppArgs[], + uno_Any **ppException + ); + +} + diff --git a/bridges/source/remote/urp/urp_environment.cxx b/bridges/source/remote/urp/urp_environment.cxx new file mode 100644 index 000000000000..46773c8f427b --- /dev/null +++ b/bridges/source/remote/urp/urp_environment.cxx @@ -0,0 +1,431 @@ +/************************************************************************* + * + * $RCSfile: urp_environment.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <assert.h> +#include <stdio.h> + +#include <osl/interlck.h> +#include <osl/diagnose.h> +#include <osl/conditn.h> +#include <osl/mutex.hxx> + +#include <rtl/alloc.h> +#include <rtl/uuid.h> +#include <vos/thread.hxx> + +#include <uno/environment.h> +#include <uno/lbnames.h> +#include <uno/mapping.hxx> +#include <uno/threadpool.h> + +#include <com/sun/star/uno/Sequence.hxx> + +#include <bridges/remote/proxy.hxx> +#include <bridges/remote/stub.hxx> +#include <bridges/remote/context.h> +#include <bridges/remote/mapping.hxx> +#include <bridges/remote/counter.hxx> +#include <bridges/remote/bridgeimpl.hxx> +#include <bridges/remote/helper.hxx> + +#include "urp_bridgeimpl.hxx" +#include "urp_writer.hxx" +#include "urp_reader.hxx" +#include "urp_dispatch.hxx" +#include "urp_log.hxx" + +using namespace ::rtl; +using namespace ::com::sun::star::uno; + + +#define UNO_LB_URP "urp" + +namespace bridges_urp +{ + +void test_cache() +{ + OUString a = OUString( RTL_CONSTASCII_USTRINGPARAM( "a" ) ); + OUString b = OUString( RTL_CONSTASCII_USTRINGPARAM( "b" ) ); + OUString c = OUString( RTL_CONSTASCII_USTRINGPARAM( "c" ) ); + Cache < OUString , equalOUString > cache ( 2 ); + + sal_Int32 n = cache.put( a ); + sal_Int32 nR = cache.seek( a ); + OSL_ASSERT( n == nR ); + OSL_ASSERT( 0 == n ); + + n = cache.put( b ); + OSL_ASSERT( 1 == n ); + + cache.put( c ); + + OSL_ASSERT( 0xffff == cache.seek( a ) ); + OSL_ASSERT( 1 == cache.seek( b ) ); + OSL_ASSERT( 0 == cache.seek( c ) ); + + OSL_ASSERT( 1 == cache.put( a ) ); + OSL_ASSERT( 0xffff == cache.seek( b) ); + OSL_ASSERT( 1 == cache.seek( a ) ); + OSL_ASSERT( 0 == cache.seek( c ) ); +} + +/******************* + * Are we within thread, that calls destructors of static objects ? + *******************/ +sal_Bool g_bStaticDestructorsCalled = sal_False; +struct StaticSingleton +{ + ~StaticSingleton() + { + g_bStaticDestructorsCalled = sal_True; + } +}; +StaticSingleton singleton; + +#ifdef DEBUG +static MyCounter thisCounter( "Remote Environment" ); +#endif + +struct RemoteEnvironment +{ + + static void SAL_CALL thisDisposing( uno_Environment *pEnvRemote ); + static void SAL_CALL thisComputeObjectIdentifier( uno_ExtEnvironment *pEnvRemote, + rtl_uString **ppOid, + void *pInterface ); + static void SAL_CALL thisAcquireInterface( uno_ExtEnvironment * pEnvRemote , + void *pInterface ); + static void SAL_CALL thisReleaseInterface( uno_ExtEnvironment * pEnvRemote, + void *pInterface); + static void SAL_CALL thisDispose( uno_Environment *pEnvRemote ); +}; + +void SAL_CALL allThreadsAreGone( uno_Environment * pEnvRemote ) +{ + remote_Context *pContext = (remote_Context *) pEnvRemote->pContext; + urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl; + + ::osl::MutexGuard guard( pImpl->m_disposingMutex ); + + pImpl->m_cndWaitForThreads.set(); + +} + +void SAL_CALL releaseStubs( uno_Environment *pEnvRemote ) +{ + + ((remote_Context * ) pEnvRemote->pContext )->m_pBridgeImpl->m_bReleaseStubsCalled = sal_True; + + remote_Interface **ppInterfaces = 0; + sal_Int32 nCount; + pEnvRemote->pExtEnv->getRegisteredInterfaces( pEnvRemote->pExtEnv, + (void***)&ppInterfaces, + &nCount, + rtl_allocateMemory ); + + sal_Int32 i; + for( i = 0 ; i < nCount ; i ++ ) + { + if( ppInterfaces[i]->acquire == bridges_remote::Uno2RemoteStub::thisAcquire ) + { + // these are freed by the environment, so no release necessary + pEnvRemote->pExtEnv->revokeInterface( pEnvRemote->pExtEnv, ppInterfaces[i] ); + } + else + { + ppInterfaces[i]->release( ppInterfaces[i] ); + } + } + + rtl_freeMemory( (void*) ppInterfaces ); +} + +void RemoteEnvironment::thisDispose( uno_Environment *pEnvRemote ) +{ + remote_Context *pContext = (remote_Context *) pEnvRemote->pContext; + urp_BridgeImpl *pImpl = ( urp_BridgeImpl *) pContext->m_pBridgeImpl; + + ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex ); + if( pContext->m_pBridgeImpl->m_bDisposed && + ( ! pImpl->m_pReader || + osl_getThreadIdentifier(0) == + (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() ) ) + { + return; + } + // in case, that the static destructors already have been called, no + // tiding up is done. + if( ! g_bStaticDestructorsCalled && ! pContext->m_pBridgeImpl->m_bDisposed ) + { + // TODO : not threadsafe + // synchronization with dispatch methods needed ! + + pImpl->m_bDisposed = sal_True; + + + // from now on, no calls can be delivered via the bridge + uno_threadpool_disposeThreads( (sal_Int64) pEnvRemote ); + + + // close the connection + urp_sendCloseConnection( pEnvRemote ); + pImpl->m_pWriter->abort(); + pContext->m_pConnection->close( pContext->m_pConnection ); + + if( osl_getThreadIdentifier(0) == + (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() ) + { + // This is the reader thread. Let the thread destroy itself + // the reader thread object must also release the connection at this stage ! + pImpl->m_pReader->destroyYourself(); + } + else + { + // wait for the reader thread + // the reader thread object must also release the connection, + // when terminating !!!! + pImpl->m_pReader->join(); + } + + // wait for the writer thread + pImpl->m_pWriter->join(); + + // destroy the threads + delete pImpl->m_pWriter; + pImpl->m_pWriter = 0; + + if( osl_getThreadIdentifier(0) != + (oslThreadIdentifier) pImpl->m_pReader->getIdentifier() ) + { + // This is not the reader thread, so the thread object is deleted + delete pImpl->m_pReader; + } + pImpl->m_pReader = 0; + + // now let the context go ! + pContext->dispose( pContext ); + + if( 0 != pImpl->m_nRemoteThreads ) + { + // Wait for all threads + pImpl->m_cndWaitForThreads.reset(); + guard.clear(); + pImpl->m_cndWaitForThreads.wait(); + OSL_ASSERT( ! pImpl->m_nRemoteThreads ); + } + else + { + guard.clear(); + } + + // delete the stubs + releaseStubs( pEnvRemote ); + } +} + + +void RemoteEnvironment::thisDisposing( uno_Environment *pEnvRemote ) +{ + remote_Context *pContext = (remote_Context * )pEnvRemote->pContext; + urp_BridgeImpl *pImpl = ((urp_BridgeImpl*) pContext->m_pBridgeImpl); + + { + ::osl::ClearableMutexGuard guard( pImpl->m_disposingMutex ); + if( ! pImpl->m_bDisposed ) + { + guard.clear(); + thisDispose( pEnvRemote ); + } + } + + uno_threadpool_stopDisposeThreads( (sal_Int64) pEnvRemote ); + + pContext->aBase.release( (uno_Context * ) pContext ); +#ifdef DEBUG + thisCounter.release(); +#endif +} + +void RemoteEnvironment::thisComputeObjectIdentifier( uno_ExtEnvironment *pEnvRemote, + rtl_uString **ppOid , + void *pInterface) +{ + assert( 0 ); + // should never be called +} + +void RemoteEnvironment::thisAcquireInterface( uno_ExtEnvironment *pEnvRemote, void *pInterface ) +{ + ((remote_Interface *)pInterface)->acquire( ( remote_Interface *) pInterface ); +} + +void RemoteEnvironment::thisReleaseInterface( uno_ExtEnvironment *pEnvRemote, void *pInterface ) +{ + ((remote_Interface *)pInterface)->release( ( remote_Interface *) pInterface ); +} + +} // end namespace bridges_urp +using namespace bridges_urp; + +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_initEnvironment( uno_Environment * pEnvRemote ) +{ + // set C-virtual methods + pEnvRemote->environmentDisposing = RemoteEnvironment::thisDisposing; + pEnvRemote->pExtEnv->computeObjectIdentifier = RemoteEnvironment::thisComputeObjectIdentifier; + pEnvRemote->pExtEnv->acquireInterface = RemoteEnvironment::thisAcquireInterface; + pEnvRemote->pExtEnv->releaseInterface = RemoteEnvironment::thisReleaseInterface; + pEnvRemote->dispose = RemoteEnvironment::thisDispose; + + remote_Context *pContext = ( remote_Context * ) pEnvRemote->pContext; + pContext->aBase.acquire( ( uno_Context * ) pContext ); + pContext->getRemoteInstance = ::bridges_remote::remote_sendQueryInterface; + + // Initialize impl struct urp_BridgeImpl + sal_Int32 nCacheSize = 256; + sal_Int32 nTimeoutMUSEC = 10000; + sal_Int32 nFlushBlockSize = 4*1024; + + urp_BridgeImpl *pImpl = new ::bridges_urp::urp_BridgeImpl( nCacheSize, 8192 ); + pContext->m_pBridgeImpl = pImpl; + + pImpl->m_cndWaitForThreads; + pImpl->m_allThreadsAreGone = allThreadsAreGone; + pImpl->m_sendRequest = urp_sendRequest; + pImpl->m_nFlushBlockSize = nFlushBlockSize; + pImpl->m_nTimeoutMUSEC = nTimeoutMUSEC; + pImpl->m_nRemoteThreads = 0; + pImpl->m_bDisposed = sal_False; + pImpl->m_bReleaseStubsCalled = sal_False; + + pImpl->m_pWriter = new ::bridges_urp::OWriterThread( pContext->m_pConnection , pImpl ); + pImpl->m_pWriter->create(); + + pImpl->m_pReader = new ::bridges_urp::OReaderThread( pContext->m_pConnection , + pEnvRemote, + pImpl->m_pWriter ); + pImpl->m_pReader->create(); + +#ifdef BRIDGES_URP_PROT + pImpl->m_pLogFile = 0; + char *p = getenv( "PROT_REMOTE" ); + if( p ) + { + static int counter; + OString s(p); + s += OString::valueOf( (sal_Int32) counter ); + pImpl->m_pLogFile = fopen( s.getStr() , "w" ); + counter++; + } +#endif + // start reader and writer threads +#ifdef DEBUG + thisCounter.acquire(); +#endif +} + + +//################################################################################################## +extern "C" SAL_DLLEXPORT void SAL_CALL uno_ext_getMapping( + uno_Mapping ** ppMapping, + uno_Environment * pFrom, + uno_Environment * pTo ) +{ + OSL_ASSERT( ppMapping && pFrom && pTo ); + if (ppMapping && pFrom && pTo) + { + if (*ppMapping) + ((*ppMapping)->release)( *ppMapping ); + bridges_remote::RemoteMapping * pMapping = 0; + + ::rtl::OUString sFromName = pFrom->pTypeName; + ::rtl::OUString sToName = pTo->pTypeName; + ::rtl::OUString sUno = OUString::createFromAscii( UNO_LB_UNO ); + ::rtl::OUString sRemote = OUString::createFromAscii( UNO_LB_URP ); + if ( sFromName.equalsIgnoreCase( sRemote ) && + sToName.equalsIgnoreCase( sUno ) ) + { + pMapping = new bridges_remote::RemoteMapping( pTo, /* Uno */ + pFrom, /*remote*/ + bridges_remote::RemoteMapping::remoteToUno, + OUString() ); + } + else if ( sFromName.equalsIgnoreCase( sUno ) && + sToName.equalsIgnoreCase( sRemote ) ) + { + pMapping = new bridges_remote::RemoteMapping( pFrom , + pTo , + bridges_remote::RemoteMapping::unoToRemote, + OUString() ); + } + + *ppMapping = (uno_Mapping * )pMapping; + OUString dummy; + uno_registerMapping( ppMapping , + bridges_remote::RemoteMapping::thisFree, + pFrom , + pTo , + dummy.pData ); + } +} + + diff --git a/bridges/source/remote/urp/urp_job.cxx b/bridges/source/remote/urp/urp_job.cxx new file mode 100644 index 000000000000..7768e4493b82 --- /dev/null +++ b/bridges/source/remote/urp/urp_job.cxx @@ -0,0 +1,540 @@ +/************************************************************************* + * + * $RCSfile: urp_job.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <string.h> +#include <stdio.h> + +#include <osl/diagnose.h> +#include <osl/mutex.hxx> + +#include <rtl/alloc.h> + +#include <uno/threadpool.h> + +#include <bridges/cpp_uno/type_misc.hxx> +#include <bridges/remote/proxy.hxx> + +#include <com/sun/star/uno/Any.hxx> + +#include "urp_job.hxx" +#include "urp_bridgeimpl.hxx" +#include "urp_writer.hxx" +#include "urp_dispatch.hxx" +#include "urp_log.hxx" +#include "urp_marshal.hxx" + +using namespace ::std; +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star::uno; + + +namespace bridges_urp +{ + + Job::Job( + uno_Environment *pEnvRemote, + sal_Sequence *pTid, + struct urp_BridgeImpl *pBridgeImpl, + Unmarshal *pUnmarshal ) + : m_pTid( pTid ) + , m_counter( pEnvRemote ) + , m_pBridgeImpl( pBridgeImpl ) + , m_pUnmarshal( pUnmarshal ) + { + if( m_pTid ) + rtl_byte_sequence_acquire( pTid ); + } + + Job::~Job() + { + if( m_pTid ) + rtl_byte_sequence_release( m_pTid ); + } + + // static method + void Job::doit( void *pThis ) + { + Job *pJob = ( Job * ) pThis; + pJob->execute(); + delete pJob; + } + + + //-------------------------------------------------------------------------------------- + sal_Bool ClientJob::extract( ) + { + sal_Bool bReturn = sal_True; + + //-------------------------- + // Handle the reply, unpack data + //-------------------------- + if( m_bExceptionOccured ) + { + bReturn = m_pUnmarshal->unpackAny( *m_ppException ); + } + else + { + //--------------------------------- + // alles ist gut + //--------------------------------- + if( m_pMethodType ) + { + if( m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID ) + { + typelib_TypeDescription *pType = 0; + TYPELIB_DANGER_GET( &pType , m_pMethodType->pReturnTypeRef ); + m_pUnmarshal->unpack( m_pReturn , pType ); + TYPELIB_DANGER_RELEASE( pType ); + } + + // out parameters + sal_Int32 i; + for( i = 0 ; i < m_pMethodType->nParams ; i ++ ) + { + if( m_pMethodType->pParams[i].bOut ) + { + typelib_TypeDescription *pType = 0; + TYPELIB_DANGER_GET( &pType , m_pMethodType->pParams[i].pTypeRef ); + if( m_pMethodType->pParams[i].bIn ) + { + uno_destructData( m_ppArgs[i] , pType , ::bridges_remote::remote_release ); + } + m_pUnmarshal->unpack( m_ppArgs[i] , pType ); + TYPELIB_DANGER_RELEASE( pType ); + } + } + } + else if( m_pAttributeType && m_pReturn ) + { + typelib_TypeDescription *pType = 0; + TYPELIB_DANGER_GET( &pType , m_pAttributeType->pAttributeTypeRef ); + m_pUnmarshal->unpack( m_pReturn , pType ); + TYPELIB_DANGER_RELEASE( pType ); + } + else if( m_pAttributeType && m_ppArgs ) + { + // nothing to do + } + else + { + OSL_ASSERT( 0 ); + } + *m_ppException = 0; + } + return sal_True; + } + + void ClientJob::initiate() + { + uno_threadpool_putReply( m_pTid , (sal_Int8*) this ); + } + + + + //------------------------------------------------------------------------------------ + ServerMultiJob::ServerMultiJob( + uno_Environment *pEnvRemote, + sal_Sequence *pTid, + struct urp_BridgeImpl *pBridgeImpl, + Unmarshal *pUnmarshal ) + : Job( pEnvRemote, pTid, pBridgeImpl , pUnmarshal ) + , m_pEnvRemote( pEnvRemote ) + , m_pCurrentMem( (sal_Int8*)rtl_allocateMemory( g_nInitialMemorySize ) ) + , m_nCurrentMemPosition( 0 ) + , m_nCalls( 0 ) + { + m_pEnvRemote->acquire( m_pEnvRemote ); + } + + ServerMultiJob::~ServerMultiJob() + { + sal_Int32 i; + for( i = 0 ; i < m_nCalls ; i ++ ) + { + struct MemberTypeInfo *const pMTI = &( m_aTypeInfo[i] ); + struct ServerJobEntry *const pSJE = &( m_aEntries[i] ); + + if( pSJE->m_pRemoteI ) + pSJE->m_pRemoteI->release( pSJE->m_pRemoteI ); + + if( pSJE->m_pOid ) + rtl_uString_release( pSJE->m_pOid ); + + if( pSJE->m_pInterfaceTypeRef ) + typelib_typedescriptionreference_release( pSJE->m_pInterfaceTypeRef ); + + if( pMTI->m_pInterfaceType ) + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription *)pMTI->m_pInterfaceType ); + + for( sal_Int32 iArgs = 0 ; iArgs < pMTI->m_nArgCount ; iArgs ++ ) + { + if( pMTI->m_ppArgType[iArgs] ) + TYPELIB_DANGER_RELEASE( pMTI->m_ppArgType [iArgs] ); + } + if( pMTI->m_pReturnType ) + TYPELIB_DANGER_RELEASE( pMTI->m_pReturnType ); + + if( pMTI->m_pMethodType ) + typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pMethodType ); + if( pMTI->m_pAttributeType ) + typelib_typedescription_release( (typelib_TypeDescription*)pMTI->m_pAttributeType ); + } + + rtl_freeMemory( m_pCurrentMem ); + for( list< sal_Int8 *>::iterator ii = m_lstMem.begin() ; ii != m_lstMem.end() ; ++ii ) + rtl_freeMemory( *ii ); + + if( m_pEnvRemote ) + m_pEnvRemote->release( m_pEnvRemote ); + + } + + void ServerMultiJob::execute() + { + for( sal_Int32 i = 0; i < m_nCalls ; i ++ ) + { + struct MemberTypeInfo * const pMTI = &( m_aTypeInfo[i] ); + struct ServerJobEntry * const pSJE = &( m_aEntries[i] ); + + if( ! pSJE->m_pRemoteI ) + { + // ------------------- + // Initial object ? + // ------------------ + // be robust : Sending a release on a not constructed object + // provokes an segfault. Make sure, the call + // is not a release call. + remote_Context *pRemoteC = ((remote_Context*)m_pEnvRemote->pContext); + if( ! pMTI->m_bIsReleaseCall && pRemoteC->m_pInstanceProvider ) + { + pRemoteC->m_pInstanceProvider->getInstance( + pRemoteC->m_pInstanceProvider, + m_pEnvRemote, + &(pSJE->m_pRemoteI), + pSJE->m_pOid, + pMTI->m_pInterfaceType ); + } + + if( ! pSJE->m_pRemoteI ) + { + // Requested object could not be located in this environment, + // throw a runtimeexception + OUString sMessage( RTL_CONSTASCII_USTRINGPARAM( "urp-bridge: unknown object identifier : " ) ); + sMessage += pSJE->m_pOid; + + // prepare the exception + prepareRuntimeException( sMessage , i ); + // no interface to call on, but unmarshaling must continue to update cache + } + } + + if( pSJE->m_pException ) + { + // errors during extracting, do nothing + } + else + { + pSJE->m_pException = &(pSJE->m_exception ); + + if( pMTI->m_bIsReleaseCall ) + { + pSJE->m_pRemoteI->release( pSJE->m_pRemoteI ); + pSJE->m_pException = 0; + } + else + { + pSJE->m_pRemoteI->pDispatcher( + pSJE->m_pRemoteI, + pMTI->m_pMethodType ? (typelib_TypeDescription*) pMTI->m_pMethodType : + (typelib_TypeDescription*) pMTI->m_pAttributeType, + pSJE->m_pReturn, + pSJE->m_ppArgs, + &(pSJE->m_pException) ); + } + } + + // now destruct parameters and marshal replies + // Note : when call is synchron => m_nCalls == 1 + if( pMTI->m_pMethodType && pMTI->m_pMethodType->bOneWay ) + { + // Oneway call, destruct in parameters + for( sal_Int32 i = 0 ; i < pMTI->m_pMethodType->nParams ; i ++ ) + { + // usually all parameters must be in parameters, but to be robust ... + if( pMTI->m_pbIsIn[i] && !cppu_isSimpleType( pMTI->m_ppArgType[i] ) ) + { + uno_destructData( pSJE->m_ppArgs[i] , pMTI->m_ppArgType[i] , 0 ); + } + } + + if( pSJE->m_pException ) + { + uno_any_destruct( pSJE->m_pException, ::bridges_remote::remote_release ); + } + + } + else + { + // synchron, get the mutex to marshal reply and send immeadiatly + MutexGuard guard( m_pBridgeImpl->m_marshalingMutex ); + + sal_Bool bTid = sal_False; + sal_uInt8 nFlags = HDRFLAG_LONG; + ByteSequence tid = m_pTid; + if( !( tid == m_pBridgeImpl->m_lastOutTid ) ) + { + // new threadid + nFlags = nFlags | HDRFLAG_NEWTID; + bTid = sal_True; + } + + if( pSJE->m_pException ) + { + nFlags = nFlags | HDRFLAG_EXCEPTIONOCCURED; + } +#ifdef BRIDGES_URP_PROT + sal_Int32 nLogStart = m_pBridgeImpl->m_blockMarshaler.getPos(); +#endif + m_pBridgeImpl->m_blockMarshaler.packInt8( &nFlags ); + + if( bTid ) + { + + m_pBridgeImpl->m_lastOutTid = tid; + m_pBridgeImpl->m_blockMarshaler.packTid( tid ); + } + +#ifdef BRIDGES_URP_PROT + sal_Int32 nLogHeader = m_pBridgeImpl->m_blockMarshaler.getPos(); +#endif + + if( pSJE->m_pException ) + { + //-------------------- + // an exception was thrown + //-------------------- + m_pBridgeImpl->m_blockMarshaler.packAny( &(pSJE->m_exception) ); + uno_any_destruct( &(pSJE->m_exception) , ::bridges_remote::remote_release ); + + // destroy in parameters + for( sal_Int32 i = 0 ; i < pMTI->m_nArgCount ; i ++ ) + { + if( pMTI->m_pbIsIn[i] && ! cppu_isSimpleType( pMTI->m_ppArgType[i] )) + { + uno_destructData( pSJE->m_ppArgs[i] , pMTI->m_ppArgType[i] , + ::bridges_remote::remote_release ); + } + } + } + else + { + //--------------------------- + // alles ist gut ... + //-------------------------- + if( pMTI->m_pReturnType ) + { + m_pBridgeImpl->m_blockMarshaler.pack( + pSJE->m_pReturn, pMTI->m_pReturnType ); + if( ! cppu_isSimpleType( pMTI->m_pReturnType ) ) + { + uno_destructData( pSJE->m_pReturn , pMTI->m_pReturnType , + ::bridges_remote::remote_release ); + } + } + for( sal_Int32 i = 0 ; i < pMTI->m_nArgCount ; i ++ ) + { + if( pMTI->m_pbIsOut[i] ) + { + m_pBridgeImpl->m_blockMarshaler.pack( + pSJE->m_ppArgs[i] , pMTI->m_ppArgType[i] ); + } + if( ! cppu_isSimpleType( pMTI->m_ppArgType[i] ) ) + { + uno_destructData( pSJE->m_ppArgs[i], pMTI->m_ppArgType[i] , + ::bridges_remote::remote_release ); + } + } + } + +#ifdef BRIDGES_URP_PROT + { + typelib_InterfaceMemberTypeDescription *pMemberType = + pMTI->m_pMethodType ? + (typelib_InterfaceMemberTypeDescription*)pMTI->m_pMethodType : + (typelib_InterfaceMemberTypeDescription*)pMTI->m_pAttributeType; + + urp_logReplying( m_pBridgeImpl , + m_pBridgeImpl->m_blockMarshaler.getPos() - nLogStart, + m_pBridgeImpl->m_blockMarshaler.getPos() - nLogHeader, + pMemberType->pMemberName ); + } +#endif + + if( pSJE->m_pRemoteI ) + { + pSJE->m_pRemoteI->release( pSJE->m_pRemoteI ); + pSJE->m_pRemoteI = 0; + } + + // put it on the wire + m_pBridgeImpl->m_pWriter->touch( sal_True ); + } // MutexGuard marshalingMutex + } + } + + void ServerMultiJob::prepareRuntimeException( const OUString & sMessage , sal_Int32 nCall ) + { + // ------------------------------- + // Construct the RuntimeException + // ------------------------------- + + typelib_TypeDescription *pType = 0; + getCppuType( (RuntimeException * ) 0 ).getDescription(&pType ); + + OSL_ENSURE( pType , "urp-bridge: couldn't get RuntimeException type" ); + + m_aEntries[nCall].m_pException = &(m_aEntries[nCall].m_exception); + uno_any_construct( m_aEntries[nCall].m_pException , 0 , pType , 0 ); + + typelib_typedescription_release( pType ); + } + + void ServerMultiJob::initiate() + { + uno_threadpool_putRequest( + m_pTid, this, doit, + m_aTypeInfo[0].m_pMethodType && m_aTypeInfo[0].m_pMethodType->bOneWay ); + } + + + // this method is called by the dispatcher thread to unmarshal a request + sal_Bool ServerMultiJob::extract() + { + sal_Bool bContinue = sal_True; + struct MemberTypeInfo * const pMTI = &(m_aTypeInfo[m_nCalls]); + struct ServerJobEntry * const pSJE = &(m_aEntries[m_nCalls]); + + pSJE->m_pException = 0; + pSJE->m_ppArgs = 0; + pSJE->m_pReturn = 0; + pMTI->m_pReturnType = 0; + + if( pMTI->m_nArgCount ) + { + pMTI->m_ppArgType = + ( typelib_TypeDescription ** ) getHeap( sizeof(void*) * pMTI->m_nArgCount ); + pSJE->m_ppArgs = (void**) getHeap( sizeof( void * ) * pMTI->m_nArgCount ); + pMTI->m_pbIsIn = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount ); + pMTI->m_pbIsOut = (sal_Bool *) getHeap( sizeof( sal_Bool ) * pMTI->m_nArgCount ); + } + if( pMTI->m_pMethodType && + pMTI->m_pMethodType->pReturnTypeRef->eTypeClass != typelib_TypeClass_VOID ) + { + TYPELIB_DANGER_GET( &(pMTI->m_pReturnType), pMTI->m_pMethodType->pReturnTypeRef ); + } + else if( pMTI->m_pAttributeType && ! pMTI->m_nArgCount ) + { + TYPELIB_DANGER_GET( &(pMTI->m_pReturnType) , pMTI->m_pAttributeType->pAttributeTypeRef ); + } + + // normal method + if( pMTI->m_pMethodType ) + { + for( sal_Int32 i = 0 ; i < pMTI->m_nArgCount ; i ++ ) + { + pMTI->m_ppArgType[i] = 0; + TYPELIB_DANGER_GET( & ( pMTI->m_ppArgType[i] ) , pMTI->m_pMethodType->pParams[i].pTypeRef); + pMTI->m_pbIsIn[i] = pMTI->m_pMethodType->pParams[i].bIn; + pMTI->m_pbIsOut[i] = pMTI->m_pMethodType->pParams[i].bOut; + + pSJE->m_ppArgs[i] = getHeap( pMTI->m_ppArgType[i]->nSize ); + if( pMTI->m_pbIsIn[i] ) + { + // everything needs to be constructed + bContinue = m_pUnmarshal->unpack( + pSJE->m_ppArgs[i], pMTI->m_ppArgType[i] ) && bContinue; + } + } + } + else if( pMTI->m_nArgCount ) + { + // set attribut + pMTI->m_ppArgType[0] = 0; + pMTI->m_pbIsIn[0] = sal_True; + pMTI->m_pbIsOut[0] = sal_False; + TYPELIB_DANGER_GET( + & ( pMTI->m_ppArgType[0] ) , pMTI->m_pAttributeType->pAttributeTypeRef ); + pSJE->m_ppArgs[0] = getHeap( pMTI->m_ppArgType[0]->nSize ); + bContinue = m_pUnmarshal->unpack( + pSJE->m_ppArgs[0], pMTI->m_ppArgType[0] ) && bContinue; + } + + if( pMTI->m_pReturnType ) + { + pSJE->m_pReturn = getHeap( pMTI->m_pReturnType->nSize ); + } + + m_nCalls ++; + return bContinue; + } +} + + diff --git a/bridges/source/remote/urp/urp_job.hxx b/bridges/source/remote/urp/urp_job.hxx new file mode 100644 index 000000000000..6a716c036255 --- /dev/null +++ b/bridges/source/remote/urp/urp_job.hxx @@ -0,0 +1,276 @@ +/************************************************************************* + * + * $RCSfile: urp_job.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <list> +#include <typelib/typedescription.hxx> +#include <uno/any2.h> +#include <uno/environment.h> + +#include "urp_threadid.hxx" +#include "urp_unmarshal.hxx" +#include <bridges/remote/bridgeimpl.hxx> + +const sal_Int32 MAX_ENTRIES_IN_MULTIJOB = 60; +const sal_Int32 g_nInitialMemorySize = 6192; + + +namespace bridges_urp +{ +class Unmarshal; +struct urp_BridgeImpl; + +template < class t > +inline t mymax( const t &t1 , const t &t2 ) +{ + return t1 > t2 ? t1 : t2; +} + +class Job +{ +public: + Job( uno_Environment *pEnvRemote, + sal_Sequence *pTid, + struct urp_BridgeImpl *pBridgeImpl, + Unmarshal *pUnmarshal ); + + Job( uno_Environment *pEnvRemote, + struct urp_BridgeImpl *pBridgeImpl, + ::bridges_remote::RemoteThreadCounter_HoldEnvWeak value ) + : m_counter( pEnvRemote , value ) + , m_pBridgeImpl( pBridgeImpl ) + , m_pTid( 0 ) + {} + + virtual ~Job(); + + // doit method is used only for ServerJobs, calls execute and pack + static void SAL_CALL doit( void *pThreadSpecificData ); + + // is called from the dispatcher thread + virtual sal_Bool extract( ) = 0; + virtual void initiate() = 0; + virtual void execute() = 0; + + inline void setThreadId( sal_Sequence *pId ) + { rtl_byte_sequence_assign( &m_pTid , pId ); } + inline void setUnmarshal( Unmarshal *p ) + { m_pUnmarshal = p; } + +protected: + Unmarshal *m_pUnmarshal; + struct urp_BridgeImpl *m_pBridgeImpl; + sal_Sequence *m_pTid; + ::bridges_remote::RemoteThreadCounter m_counter; +}; + +class ClientJob : public Job +{ +public: + ClientJob( uno_Environment *pEnvRemote, struct urp_BridgeImpl *pBridgeImpl ) + : Job( pEnvRemote , pBridgeImpl, ::bridges_remote::RTC_HOLDENVWEAK ) + , m_ppException( 0 ) + , m_ppArgs( 0 ) + , m_pReturn( 0 ) + , m_pMethodType( 0 ) + , m_pAttributeType( 0 ) + {} + + // ~ClientJob + // no release for method type and attribute type necessary, because + // it was acquired by the caller of urp_sendRequest. The lifetime + // of the ClientJob object is always shorter than the urp_sendRequest call. + ~ClientJob() + {} + + virtual sal_Bool extract( ); + virtual void initiate(); + virtual void execute() + {} + +public: + void **m_ppArgs; + void *m_pReturn; + typelib_InterfaceMethodTypeDescription *m_pMethodType; + typelib_InterfaceAttributeTypeDescription *m_pAttributeType; + + uno_Any **m_ppException; + sal_Bool m_bExceptionOccured; +}; + + +struct MemberTypeInfo +{ + typelib_InterfaceTypeDescription *m_pInterfaceType; + typelib_InterfaceMethodTypeDescription *m_pMethodType; + typelib_InterfaceAttributeTypeDescription *m_pAttributeType; + sal_Int32 m_nArgCount; + sal_Bool m_bIsReleaseCall; + sal_Bool *m_pbIsIn; + sal_Bool *m_pbIsOut; + typelib_TypeDescription *m_pReturnType; + typelib_TypeDescription **m_ppArgType; +}; + + +struct ServerJobEntry +{ + rtl_uString *m_pOid; + remote_Interface *m_pRemoteI; + typelib_TypeDescriptionReference *m_pInterfaceTypeRef; + void **m_ppArgs; + void *m_pReturn; + uno_Any m_exception; + uno_Any *m_pException; + +}; + +class ServerMultiJob : public Job +{ +public: + ServerMultiJob( uno_Environment *pEnvRemote, + sal_Sequence *pTid, + struct urp_BridgeImpl *pBridgeImpl, + Unmarshal *pUnmarshal); + ~ServerMultiJob(); +public: + virtual sal_Bool extract( ); + virtual void initiate(); + virtual void execute(); + +public: + // setMethodType or setAttributeType MUST be called before extract + inline void setMethodType( typelib_InterfaceMethodTypeDescription *pMethodType, sal_Bool bIsReleaseCall) + { + m_aTypeInfo[m_nCalls].m_pMethodType = pMethodType; + m_aTypeInfo[m_nCalls].m_pAttributeType = 0; + m_aTypeInfo[m_nCalls].m_nArgCount = pMethodType->nParams; + m_aTypeInfo[m_nCalls].m_bIsReleaseCall = bIsReleaseCall; + } + + inline void setAttributeType( typelib_InterfaceAttributeTypeDescription *pAttributeType, sal_Bool bIsSetter ) + { + m_aTypeInfo[m_nCalls].m_pAttributeType = pAttributeType; + m_aTypeInfo[m_nCalls].m_pMethodType = 0; + m_aTypeInfo[m_nCalls].m_nArgCount = bIsSetter ? 1 : 0; + m_aTypeInfo[m_nCalls].m_bIsReleaseCall = sal_False; + } + + inline void setType( const ::com::sun::star::uno::Type &type ) + { + m_aEntries[m_nCalls].m_pInterfaceTypeRef = type.getTypeLibType(); + typelib_typedescriptionreference_acquire( m_aEntries[m_nCalls].m_pInterfaceTypeRef ); + TYPELIB_DANGER_GET( + (typelib_TypeDescription ** )&(m_aTypeInfo[m_nCalls].m_pInterfaceType) , + type.getTypeLibType() ); + } + // setOid or setInterface MUST be called before extract + inline void setOid( const ::rtl::OUString & sOid ) + { + m_aEntries[m_nCalls].m_pOid = sOid.pData; + rtl_uString_acquire( m_aEntries[m_nCalls].m_pOid ); + m_aEntries[m_nCalls].m_pRemoteI = 0; + } + + // setOid or setInterface MUST be called + inline void setInterface( remote_Interface *pRemoteI ) + { + m_aEntries[m_nCalls].m_pRemoteI = pRemoteI; + pRemoteI->acquire( pRemoteI ); + m_aEntries[m_nCalls].m_pOid = 0; + } + + inline sal_Bool isFull() + { return m_nCalls >= MAX_ENTRIES_IN_MULTIJOB; } + + inline sal_Int8 *getHeap( sal_Int32 nSizeToAlloc ) + { + if( nSizeToAlloc + m_nCurrentMemPosition > g_nInitialMemorySize ) + { + m_lstMem.push_back( m_pCurrentMem ); + m_pCurrentMem = (sal_Int8*) + rtl_allocateMemory( mymax( nSizeToAlloc , g_nInitialMemorySize ) ); + m_nCurrentMemPosition = 0; + } + sal_Int8 *pHeap = m_pCurrentMem + m_nCurrentMemPosition; + m_nCurrentMemPosition += nSizeToAlloc; + + // care for alignment + if( m_nCurrentMemPosition & 0x7 ) + { + m_nCurrentMemPosition = ( ((sal_uInt32)m_nCurrentMemPosition) & ( 0xffffffff - 0x7 )) + 8; + } + return pHeap; + } + void prepareRuntimeException( const ::rtl::OUString &sMessage, sal_Int32 nCall ); + +private: + uno_Environment *m_pEnvRemote; + sal_Int32 m_nCalls; + ServerJobEntry m_aEntries[MAX_ENTRIES_IN_MULTIJOB]; + MemberTypeInfo m_aTypeInfo[MAX_ENTRIES_IN_MULTIJOB]; + + sal_Int8 *m_pCurrentMem; + sal_Int32 m_nCurrentMemPosition; + + // list of memory pointers, that must be freed + ::std::list< sal_Int8 * > m_lstMem; +}; + +} diff --git a/bridges/source/remote/urp/urp_log.cxx b/bridges/source/remote/urp/urp_log.cxx new file mode 100644 index 000000000000..5a0ce0f184c3 --- /dev/null +++ b/bridges/source/remote/urp/urp_log.cxx @@ -0,0 +1,127 @@ +/************************************************************************* + * + * $RCSfile: urp_log.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 "urp_bridgeimpl.hxx" +#include "urp_log.hxx" + +using namespace ::rtl; +namespace bridges_urp +{ +#ifdef BRIDGES_URP_PROT + void urp_logCall( urp_BridgeImpl *pBridgeImpl, sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron , + const ::rtl::OUString &sMethodName ) + { + if( pBridgeImpl->m_pLogFile && getenv( "PROT_REMOTE_ACTIVATE" ) ) + { + OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US ); + fprintf( pBridgeImpl->m_pLogFile , + "calling [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n" , + nSize, nUseData, bSynchron, sOperation.pData->buffer ); + } + } + + void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl, + sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron , + const ::rtl::OUString &sMethodName ) + { + if( pBridgeImpl->m_pLogFile && getenv( "PROT_REMOTE_ACTIVATE" ) ) + { + OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US ); + fprintf( + pBridgeImpl->m_pLogFile, + "serving request [size=%d(usedata=%d)] [synchron=%d] [name=%s]\n", + nSize, + nUseData, + bSynchron, + sOperation.pData->buffer + ); + + } + } + + void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl, + sal_Int32 nSize, sal_Int32 nUseData, + const ::rtl::OUString &sMethodName ) + { + if( pBridgeImpl->m_pLogFile && getenv( "PROT_REMOTE_ACTIVATE" ) ) + { + OString sOperation = OUStringToOString( sMethodName,RTL_TEXTENCODING_ASCII_US ); + fprintf( pBridgeImpl->m_pLogFile, + "getting reply [size=%d(usedata=%d)][name=%s]\n" , + nSize, nUseData, + sOperation.pData->buffer); + } + } + + void urp_logReplying( urp_BridgeImpl *pBridgeImpl, + sal_Int32 nSize , sal_Int32 nUseData, + const ::rtl::OUString &sMethodName ) + { + if( pBridgeImpl->m_pLogFile && getenv( "PROT_REMOTE_ACTIVATE" ) ) + { + OString sOperation = OUStringToOString(sMethodName,RTL_TEXTENCODING_ASCII_US); + fprintf( pBridgeImpl->m_pLogFile, + "replying [size=%d(usedata=%d)] [name=%s]\n", + nSize, nUseData, + sOperation.pData->buffer); + } + } +#endif +} diff --git a/bridges/source/remote/urp/urp_log.hxx b/bridges/source/remote/urp/urp_log.hxx new file mode 100644 index 000000000000..cc697a22ba81 --- /dev/null +++ b/bridges/source/remote/urp/urp_log.hxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * $RCSfile: urp_log.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +namespace bridges_urp +{ +#ifndef PRODUCT +#define BRIDGES_URP_PROT +#endif + +#ifdef BRIDGES_URP_PROT + void urp_logCall( urp_BridgeImpl *pBridgeImpl , + sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron , + const ::rtl::OUString &sMethodName ); + + void urp_logServingRequest( urp_BridgeImpl *pBridgeImpl, + sal_Int32 nSize, sal_Int32 nUseData, sal_Bool bSynchron , + const ::rtl::OUString &sMethodName ); + + void urp_logGettingReply( urp_BridgeImpl *pBridgeImpl, + sal_Int32 nSize, sal_Int32 nUseData, + const ::rtl::OUString &sMethodName ); + + void urp_logReplying( urp_BridgeImpl *pBridgeImpl, + sal_Int32 nSize , sal_Int32 nUseData, + const ::rtl::OUString &sMethodName ); +#endif +} diff --git a/bridges/source/remote/urp/urp_marshal.cxx b/bridges/source/remote/urp/urp_marshal.cxx new file mode 100644 index 000000000000..c2a6f6ad2765 --- /dev/null +++ b/bridges/source/remote/urp/urp_marshal.cxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * $RCSfile: urp_marshal.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <string.h> +#include <osl/diagnose.h> + +#include <rtl/alloc.h> + +#include <uno/any2.h> +#include <uno/sequence2.h> + +#include "urp_marshal.hxx" + +using namespace ::rtl; + +using namespace ::com::sun::star::uno; + +namespace bridges_urp { + +static int g_nDetectLittleEndian = 1; +char g_bMarshalSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0]; + +Marshal::Marshal( urp_BridgeImpl *pBridgeImpl, + sal_Int32 nBufferSize, + urp_extractOidCallback callback) : + m_callback( callback ), + m_nBufferSize( nBufferSize ), + m_base( (sal_Int8*)rtl_allocateMemory( nBufferSize ) ), + m_pos( m_base + 5 ), + m_nSizeOffset( 0 ), + m_pBridgeImpl( pBridgeImpl ) +{} + +Marshal::~Marshal( ) +{ + rtl_freeMemory( m_base ); +} + +void Marshal::packOid( const ::rtl::OUString & oid ) +{ + sal_uInt16 nIndex; + if( oid.getLength() ) + { + nIndex = m_pBridgeImpl->m_oidCacheOut.seek( oid ); + if( 0xffff == nIndex ) + { + nIndex = m_pBridgeImpl->m_oidCacheOut.put( oid ); + packString( (void*)(&oid.pData) ); + } + else + { + OUString dummy; + packString( &dummy ); + } + } + else + { + // null reference + sal_uInt16 nIndex = 0xffff; + OUString dummy; + packString( &dummy ); + } + packInt16( &nIndex ); +} + +void Marshal::packTid( const ByteSequence & threadId ) +{ + sal_uInt16 nIndex = m_pBridgeImpl->m_tidCacheOut.seek( threadId ); + if( 0xffff == nIndex ) + { + nIndex = m_pBridgeImpl->m_tidCacheOut.put( threadId ); + packByteSequence( (sal_Int8*) threadId.getConstArray() ,threadId.getLength()); + } + else + { + packByteSequence( 0 , 0 ); + } + packInt16( &nIndex ); +} + + +void Marshal::packType( void *pSource ) +{ + typelib_TypeDescriptionReference *pRef = + *(typelib_TypeDescriptionReference ** ) pSource; + + OSL_ASSERT( pRef ); + Type type( pRef ); + + sal_uInt8 nTypeClass = type.getTypeClass(); + + if( nTypeClass <= /* any*/ 14 ) + { + packInt8( (sal_Int8*)&nTypeClass ); + } + else + { + OUString sTypeName; + sal_uInt16 nIndex = 0xffff; + + nIndex = m_pBridgeImpl->m_typeCacheOut.seek( type ); + if( 0xffff == nIndex ) + { + // put it into the cache + nIndex = m_pBridgeImpl->m_typeCacheOut.put( type ); + sTypeName = type.getTypeName(); + nTypeClass = nTypeClass | 0x80; + } + packInt8( &nTypeClass ); + packInt16( &nIndex ); + if( 0x80 & nTypeClass ) + { + packString( &sTypeName ); + } + } +} + +void Marshal::packRecursive( void *pSource , typelib_TypeDescription *pType ) +{ + switch( pType->eTypeClass ) + { + case typelib_TypeClass_EXCEPTION: + case typelib_TypeClass_STRUCT: + { + typelib_CompoundTypeDescription * pCompType = (typelib_CompoundTypeDescription*)pType; + + if (pCompType->pBaseTypeDescription) + { + pack( pSource , (typelib_TypeDescription*) pCompType->pBaseTypeDescription ); + } + + // then construct members + typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs; + sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets; + sal_Int32 nDescr = pCompType->nMembers; + + for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos ) + { + typelib_TypeDescription * pMemberType = 0; + TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] ); + pack( (char*)pSource + pMemberOffsets[nPos] , pMemberType ); + TYPELIB_DANGER_RELEASE( pMemberType ); + } + break; + } + case typelib_TypeClass_SEQUENCE: + { + typelib_IndirectTypeDescription *pIndirectType = + ( typelib_IndirectTypeDescription* ) pType; + + const sal_Int32 nElements = (*(uno_Sequence **)pSource)->nElements; + char * pSourceElements = (char *)(*(uno_Sequence **)pSource)->elements; + + if( typelib_TypeClass_BYTE == pIndirectType->pType->eTypeClass ) + { + // Byte sequences are optimized + packByteSequence( (sal_Int8*)pSourceElements , nElements ); + } + else + { + typelib_TypeDescription *pElementType = 0; + TYPELIB_DANGER_GET( &pElementType, pIndirectType->pType ); + if( pElementType ) + { + const sal_Int32 nElementSize = pElementType->nSize; + + packCompressedSize( nElements ); + for ( sal_Int32 i = 0 ; i < nElements; i++ ) + { + pack( pSourceElements + (nElementSize*i) , pElementType ); + } + TYPELIB_DANGER_RELEASE( pElementType ); + } + } + + break; + } + default: + OSL_ASSERT( 0 ); + } +} + +} // end namespace bridges diff --git a/bridges/source/remote/urp/urp_marshal.hxx b/bridges/source/remote/urp/urp_marshal.hxx new file mode 100644 index 000000000000..80426ea9f71e --- /dev/null +++ b/bridges/source/remote/urp/urp_marshal.hxx @@ -0,0 +1,378 @@ +/************************************************************************* + * + * $RCSfile: urp_marshal.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _URP_MARSHAL_HXX_ +#define _URP_MARSHAL_HXX_ + +/************************************************************************** +#* +#* last change $Author: hr $ $Date: 2000-09-18 15:28:50 $ +#* $Revision: 1.1.1.1 $ +#* +#* $Logfile: $ +#* +#* Copyright (c) 2000, Sun Microsystems +#* +#************************************************************************/ +#include <rtl/ustring.hxx> +#include <rtl/byteseq.hxx> + +#include <com/sun/star/uno/Type.hxx> + +#include "urp_bridgeimpl.hxx" +#include "urp_marshal_decl.hxx" + +struct remote_Interface; + + +namespace bridges_urp +{ + // methods for accessing marshaling buffer + inline void Marshal::finish() + { + sal_Int32 nSize = ( ((sal_uInt32 )(m_pos - m_base)) -5 ); + OSL_ASSERT( nSize ); + sal_Int8 *pos = m_pos; + m_pos = m_base; + packCompressedSize( nSize ); + if( m_pos == m_base +1 ) + { + ((sal_uInt8*)m_base)[4] = (sal_uInt8) ((sal_uInt8*)m_base)[0]; + m_nSizeOffset = 4; + } + else + { + m_nSizeOffset = 0; + } + m_pos = pos; + } + + inline void Marshal::restart() + { + m_pos = m_base +5; + m_nSizeOffset = 0; + } + + inline sal_Int8 *Marshal::getBuffer() + { + return m_base + m_nSizeOffset; + } + + inline sal_Bool Marshal::empty() const + { + return ( m_pos -m_base ) == 5; + } + + inline sal_Int32 Marshal::getSize() + { + return (sal_Int32)(m_pos - m_base) - m_nSizeOffset; + } + + inline void Marshal::ensureAdditionalMem( sal_Int32 nMemToAdd ) + { + sal_Int32 nDiff = m_pos - m_base; + if( nDiff + nMemToAdd > m_nBufferSize ) + { + m_nBufferSize = m_nBufferSize * 2 > nDiff + nMemToAdd ? + m_nBufferSize* 2 : + nDiff + nMemToAdd; + + m_base = ( sal_Int8 * ) rtl_reallocateMemory( m_base , m_nBufferSize ); + m_pos = m_base + nDiff; + } + } + + + // marshaling methods + inline void Marshal::packInt8( void *pSource ) + { + ensureAdditionalMem( 1 ); + *m_pos = *((sal_Int8*) pSource ); + m_pos++; + } + + inline void Marshal::packInt16( void *pSource ) + { + ensureAdditionalMem( 2 ); + sal_uInt16 *p = ( sal_uInt16 * ) pSource; + if( isSystemLittleEndian() ) + { + m_pos[0] = ((unsigned char *)pSource)[1]; + m_pos[1] = ((unsigned char *)pSource)[0]; + } + else + { + m_pos[1] = ((unsigned char *)pSource)[1]; + m_pos[0] = ((unsigned char *)pSource)[0]; + } + m_pos +=2; + } + + inline void Marshal::packByteSequence( sal_Int8 *pData , sal_Int32 nLength ) + { + packCompressedSize( nLength ); + + ensureAdditionalMem( nLength ); + memcpy( m_pos , pData , nLength ); + m_pos += nLength; + } + + inline void Marshal::packString( void *pSource ) + { + rtl_uString *p = *( rtl_uString ** ) pSource; + + // to be optimized ! + // static buffer in marshal + ::rtl::OString o = ::rtl::OUStringToOString( p , RTL_TEXTENCODING_UTF8 ); + sal_Int32 nLength = o.pData->length; + packCompressedSize( nLength ); + + ensureAdditionalMem( nLength ); + + memcpy( m_pos , o.pData->buffer , nLength ); + m_pos += nLength; + } + + inline void Marshal::packAny( void *pSource ) + { + uno_Any *pAny = (uno_Any * ) pSource; + + // pack the type + packType( &( pAny->pType ) ); + // pack the value + typelib_TypeDescription *pType = 0; + TYPELIB_DANGER_GET( &pType, pAny->pType ); + pack( pAny->pData , pType ); + TYPELIB_DANGER_RELEASE( pType ); + } + + inline void Marshal::packInt32( void *pSource ) + { + ensureAdditionalMem( 4 ); + if( isSystemLittleEndian() ) + { + m_pos[0] = ((unsigned char *)pSource)[3]; + m_pos[1] = ((unsigned char *)pSource)[2]; + m_pos[2] = ((unsigned char *)pSource)[1]; + m_pos[3] = ((unsigned char *)pSource)[0]; + } + else { + m_pos[3] = ((unsigned char *)pSource)[3]; + m_pos[2] = ((unsigned char *)pSource)[2]; + m_pos[1] = ((unsigned char *)pSource)[1]; + m_pos[0] = ((unsigned char *)pSource)[0]; + } + m_pos +=4; + } + + + inline void Marshal::packCompressedSize( sal_Int32 nSize ) + { + ensureAdditionalMem( 5 ); + + if( nSize < 0xff ) + { + *((sal_uInt8*)m_pos) = (sal_uInt8) nSize; + m_pos ++; + } + else + { + *((sal_uInt8*)m_pos) = 0xff; + m_pos ++; + packInt32( &nSize ); + } + } + + + inline void Marshal::pack( void *pSource , typelib_TypeDescription *pType ) + { + switch( pType->eTypeClass ) + { + case typelib_TypeClass_BYTE: + { + packInt8( pSource ); + break; + } + case typelib_TypeClass_BOOLEAN: + { + ensureAdditionalMem( 1 ); + *m_pos = ( *((sal_Bool*) pSource ) ) ? 1 : 0; + m_pos++; + break; + } + + case typelib_TypeClass_CHAR: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + { + packInt16( pSource ); + break; + } + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_FLOAT: + { + packInt32( pSource ); + break; + } + case typelib_TypeClass_DOUBLE: + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + { + ensureAdditionalMem( 8 ); + if( isSystemLittleEndian() ) + { + m_pos[0] = ((unsigned char *)pSource)[7]; + m_pos[1] = ((unsigned char *)pSource)[6]; + m_pos[2] = ((unsigned char *)pSource)[5]; + m_pos[3] = ((unsigned char *)pSource)[4]; + m_pos[4] = ((unsigned char *)pSource)[3]; + m_pos[5] = ((unsigned char *)pSource)[2]; + m_pos[6] = ((unsigned char *)pSource)[1]; + m_pos[7] = ((unsigned char *)pSource)[0]; + } + else + { + m_pos[7] = ((unsigned char *)pSource)[7]; + m_pos[6] = ((unsigned char *)pSource)[6]; + m_pos[5] = ((unsigned char *)pSource)[5]; + m_pos[4] = ((unsigned char *)pSource)[4]; + m_pos[3] = ((unsigned char *)pSource)[3]; + m_pos[2] = ((unsigned char *)pSource)[2]; + m_pos[1] = ((unsigned char *)pSource)[1]; + m_pos[0] = ((unsigned char *)pSource)[0]; + } + m_pos += 8; + break; + } + + case typelib_TypeClass_STRING: + { + packString( pSource ); + break; + } + case typelib_TypeClass_TYPE: + { + packType( pSource ); + break; + } + case typelib_TypeClass_ANY: + { + packAny( pSource ); + break; + } + case typelib_TypeClass_ENUM: + { + sal_uInt32 nValue = *(sal_Int32*)pSource; + packCompressedSize( nValue ); + break; + } + case typelib_TypeClass_TYPEDEF: + { + OSL_ASSERT( 0 ); // should never occur + break; + } + case typelib_TypeClass_INTERFACE: + { + remote_Interface *pRemoteI = *( remote_Interface ** )pSource; + + ::rtl::OUString sOid; + sal_uInt16 nIndex = 0xffff; + if( pRemoteI ) + { + m_callback( pRemoteI , &(sOid.pData) ); + + nIndex = m_pBridgeImpl->m_oidCacheOut.seek( sOid ); + if( 0xffff == nIndex ) + { + nIndex = m_pBridgeImpl->m_oidCacheOut.put( sOid ); + } + else + { + // cached ! + sOid = ::rtl::OUString(); + } + } + packString( &sOid ); + packInt16( &nIndex ); + break; + } + case typelib_TypeClass_VOID: + { + // do nothing + break; + } + case typelib_TypeClass_EXCEPTION: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_SEQUENCE: + { + packRecursive( pSource, pType ); + break; + } + default: + OSL_ASSERT( 0 ); + } + } +} + + + +#endif + diff --git a/bridges/source/remote/urp/urp_marshal_decl.hxx b/bridges/source/remote/urp/urp_marshal_decl.hxx new file mode 100644 index 000000000000..50007b48ded8 --- /dev/null +++ b/bridges/source/remote/urp/urp_marshal_decl.hxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * $RCSfile: urp_marshal_decl.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * Copyright according the GNU Public License. + * + ************************************************************************/ +#ifndef _URP_MARSHAL_DECL_HXX_ +#define _URP_MARSHAL_DECL_HXX_ + +/************************************************************************** +#* +#* last change $Author: hr $ $Date: 2000-09-18 15:28:50 $ +#* $Revision: 1.1.1.1 $ +#* +#* $Logfile: $ +#* +#* Copyright (c) 2000, Sun Microsystems +#* +#************************************************************************/ +#include <rtl/ustring.hxx> +#include <rtl/byteseq.hxx> + +#include <com/sun/star/uno/Type.hxx> + +namespace bridges_urp +{ + struct urp_BridgeImpl; + + typedef void ( SAL_CALL * urp_extractOidCallback ) ( + remote_Interface *pRemoteI, + rtl_uString **ppOid ); + + extern char g_bMarshalSystemIsLittleEndian; + class Marshal + { + public: + Marshal( /* cache access */ struct urp_BridgeImpl *, + sal_Int32 m_nBufferSize, + urp_extractOidCallback callback = 0 + ); + ~Marshal( ); + + inline void pack( void *pSource , typelib_TypeDescription *pType ); + + void packRecursive( void *pSource, typelib_TypeDescription *pType ); + + void packTid( const ::rtl::ByteSequence &id ); + void packOid( const ::rtl::OUString &oid ); + void packType( void *pSource ); + + inline void packCompressedSize( sal_Int32 nSize ); + inline void packInt8( void *pSource ); + inline void packInt16( void *pSource ); + inline void packInt32( void *pSource ); + inline void packString( void *pSource ); + inline void packAny( void *pSource ); + inline void packByteSequence( sal_Int8 *pBuffer , sal_Int32 nSize ); + + // can be called during marshaling, but not between + // finish and restart + // returns true, when nothing has been marshaled + inline sal_Bool empty() const; + + // stops marshaling, inserts size in front of the buffer + // getStart and getSize can now be called + inline void finish(); + + // must be called after finish. After calling restart, + // a new marshalling session is started invalidating + // the previous bufer + inline void restart(); + + // is only valid, after finish has been called. + // valid until destructed. + inline sal_Int8 *getBuffer(); + + // is only valid, after finish has been called. + // valid until destructed. + inline sal_Int32 getSize(); + + inline sal_Int32 getPos() + { return m_pos - m_base; } + + inline sal_Bool isSystemLittleEndian() + { return g_bMarshalSystemIsLittleEndian; } + + private: + inline void ensureAdditionalMem( sal_Int32 nMemToAdd ); + sal_Int32 m_nBufferSize; + sal_Int8 *m_base; + + sal_Int8 *m_pos; + sal_Int32 m_nSizeOffset; + struct urp_BridgeImpl *m_pBridgeImpl; + urp_extractOidCallback m_callback; + }; +} +#endif diff --git a/bridges/source/remote/urp/urp_reader.cxx b/bridges/source/remote/urp/urp_reader.cxx new file mode 100644 index 000000000000..8ff2ffc31632 --- /dev/null +++ b/bridges/source/remote/urp/urp_reader.cxx @@ -0,0 +1,578 @@ +/************************************************************************* + * + * $RCSfile: urp_reader.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +/************************************************************************** + * $Log: not supported by cvs2svn $ + * Revision 1.7 2000/09/15 13:05:58 jbu + * extensive performance optimizations + * + * Revision 1.6 2000/09/14 15:24:00 willem.vandorp + * OpenOffice header added. + * + * Revision 1.5 2000/08/04 15:32:31 willem.vandorp + * Header and footer replaced + * + * Revision 1.4 2000/07/21 16:33:17 jbu + * robustness improved + * + * Revision 1.3 2000/07/14 13:14:42 jbu + * dispose mechanism tided up + * + * Revision 1.2 2000/07/12 10:11:59 jbu + * added logging, attribute bug fixed + * + * Revision 1.1 2000/07/10 11:36:35 jbu + * new remote protocol : urp + * + *************************************************************************/ +#include <string.h> + +#include <osl/diagnose.h> + +#include <bridges/remote/connection.h> +#include <bridges/remote/counter.hxx> +#include <bridges/remote/context.h> +#include <bridges/remote/helper.hxx> + +#include <uno/environment.h> + +#include "urp_reader.hxx" +#include "urp_dispatch.hxx" +#include "urp_job.hxx" +#include "urp_bridgeimpl.hxx" +#include "urp_log.hxx" + +using namespace ::rtl; +using namespace ::osl; +using namespace ::com::sun::star::uno; + +#ifdef DEBUG +static MyCounter thisCounter( "DEBUG : ReaderThread" ); +#endif + +namespace bridges_urp +{ + + inline sal_Bool getMemberTypeDescription( + typelib_InterfaceAttributeTypeDescription **ppAttributeType, + typelib_InterfaceMethodTypeDescription **ppMethodType, + sal_Bool *pbIsSetter, + sal_uInt16 nMethodId , + const Type &typeInterface) + { + if( typeInterface.getTypeClass() != typelib_TypeClass_INTERFACE ) + { + OSL_ENSURE( 0 , "type is not an interface" ); + return sal_False; + } + + typelib_InterfaceTypeDescription *pInterfaceType = 0; + TYPELIB_DANGER_GET( + (typelib_TypeDescription **)&pInterfaceType , typeInterface.getTypeLibType() ); + if( ! pInterfaceType ) + { + OString o = OUStringToOString( typeInterface.getTypeName() , RTL_TEXTENCODING_ASCII_US ); + OSL_ENSURE( !"urp: unknown type " , o.getStr() ); + return sal_False; + } + + if( ! pInterfaceType->aBase.bComplete ) + { + typelib_typedescription_complete( (typelib_TypeDescription **) &pInterfaceType ); + } + + if( nMethodId < 0 || nMethodId > pInterfaceType->nAllMembers *2 ) + { + // ( m_nMethodId > m_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; + } + + // TODO : check the range of m_nMethodId + sal_Int32 nMemberIndex = pInterfaceType->pMapFunctionIndexToMemberIndex[ nMethodId ]; + + if( !( pInterfaceType->nAllMembers > nMemberIndex && nMemberIndex >= 0 ) ) + { + OSL_ENSURE( 0 , "vtable index out of range" ); + return sal_False; + } + + typelib_InterfaceMemberTypeDescription *pMemberType = 0; + typelib_typedescriptionreference_getDescription( + (typelib_TypeDescription **) &pMemberType,pInterfaceType->ppAllMembers[nMemberIndex]); + + if(! pMemberType ) + { + OSL_ENSURE( 0 , "unknown method type description" ); + return sal_False; + } + + if( typelib_TypeClass_INTERFACE_ATTRIBUTE == pMemberType->aBase.eTypeClass ) + { + *ppAttributeType = (typelib_InterfaceAttributeTypeDescription *) pMemberType; + *pbIsSetter = ! ( + pInterfaceType->pMapMemberIndexToFunctionIndex[nMemberIndex] == nMethodId ); + } + else + { + *ppMethodType = (typelib_InterfaceMethodTypeDescription *) pMemberType; + } + + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType ); + return sal_True; + } + +OReaderThread::OReaderThread( remote_Connection *pConnection, + uno_Environment *pEnvRemote, + OWriterThread * pWriterThread ) : + m_pConnection( pConnection ), + m_pEnvRemote( pEnvRemote ), + m_pWriterThread( pWriterThread ), + m_bDestroyMyself( sal_False ), + m_pBridgeImpl((struct urp_BridgeImpl*) + ((remote_Context *)pEnvRemote->pContext)->m_pBridgeImpl ), + m_unmarshal( m_pBridgeImpl, m_pEnvRemote, ::bridges_remote::remote_createStub ) +{ + m_pConnection->acquire( m_pConnection ); +#ifdef DEBUG + thisCounter.acquire(); +#endif +} + + +OReaderThread::~OReaderThread( ) +{ +#ifdef DEBUG + thisCounter.release(); +#endif +} + +// may only be called in the callstack of this thread !!!!! +// run() -> dispose() -> destroyYourself() +void OReaderThread::destroyYourself() +{ + m_bDestroyMyself = sal_True; + m_pConnection->release( m_pConnection ); + m_pConnection = 0; +} + +void OReaderThread::onTerminated() +{ + if( m_bDestroyMyself ) + { + delete this; + } +} + + +void OReaderThread::disposeEnvironment() +{ + struct remote_Context *pContext = + ( struct remote_Context * ) m_pEnvRemote->pContext; + if( ! pContext->m_pBridgeImpl->m_bDisposed ) + { + // NOTE : This method may only be called by the run-method. + // The remote-environment does not dispose, until the reader thread has gone. + // So it is completly OK to hold the environment weakly, and only make a + // hard reference during dispose call. + m_pEnvRemote->acquire( m_pEnvRemote ); + m_pEnvRemote->dispose( m_pEnvRemote ); + m_pEnvRemote->release( m_pEnvRemote ); + } +} + +void OReaderThread::run() +{ + sal_Bool bContinue = sal_True; + while( bContinue ) + { + sal_Int32 nSize; + sal_uInt8 n8Size; + if( 1 != m_pConnection->read( m_pConnection , (sal_Int8*) &n8Size, 1) ) + { + disposeEnvironment(); + break; + } + if( 255 == n8Size ) + { + sal_uInt8 buf[4]; + m_pConnection->read( m_pConnection ,(sal_Int8*)buf, 4); + + nSize = buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; + } + else + { + nSize = ( sal_Int32 ) n8Size; + } + + if( nSize < 0 ) + { + // buffer too big + // no exception can be thrown, because there is no thread id, which could be + // used. -> terminate ! + OSL_ENSURE( 0 , "urp bridge: invalid message size, terminating connection." ); + disposeEnvironment(); + break; + } + + if( 0 == nSize ) + { + disposeEnvironment(); + break; + } + + // allocate the necessary memory + if( ! m_unmarshal.setSize( nSize ) ) + { + OSL_ENSURE( 0 , "urp bridge: messages size too large, terminating connection" ); + disposeEnvironment(); + break; + } + + sal_Int32 nRead = m_pConnection->read( m_pConnection , m_unmarshal.getBuffer() , nSize ); + + if( nSize != nRead ) + { + // 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: couldn't read complete message, terminating connection." ); + + disposeEnvironment(); + break; + } + + ServerMultiJob *pMultiJob = 0; + remote_Interface *pLastRemoteI = 0; + while( ! m_unmarshal.finished() ) + { +#ifdef BRIDGES_URP_PROT + sal_uInt32 nLogStart = m_unmarshal.getPos(); + sal_Bool bIsOneWay = sal_False; + OUString sMemberName; +#endif + sal_uInt8 nBitField; + sal_Bool bSuccess = m_unmarshal.unpackInt8( &nBitField ); + + sal_Bool bRequest = sal_True; + sal_uInt16 nMethodId = 0; + sal_Bool bType = sal_False, bOid = sal_False, bTid = sal_False; + sal_Bool bExceptionOccured = sal_False; + + if( HDRFLAG_LONG & nBitField ) + { + // this is a long header, interpret the byte as bitfield + // this is a bitfield + bTid = ( HDRFLAG_NEWTID & nBitField ); + + if( HDRFLAG_REQUEST & nBitField ) + { + bType = ( HDRFLAG_NEWTYPE & nBitField ); + bOid = ( HDRFLAG_NEWOID & nBitField ); + + // request + if( HDRFLAG_LONGMETHODID & nBitField ) + { + // methodid as unsigned short + bSuccess = bSuccess && m_unmarshal.unpackInt16( &nMethodId ); + } + else + { + sal_uInt8 id; + bSuccess = bSuccess && m_unmarshal.unpackInt8( &id ); + nMethodId = (sal_uInt16) id; + } + } + else + { + // reply + bRequest = sal_False; + bExceptionOccured = ( HDRFLAG_EXCEPTIONOCCURED & nBitField ); + } + } + else + { + // method request + synchronous-asynchronous default + if( 0x40 & nBitField ) + { + sal_uInt8 lower; + bSuccess = bSuccess && m_unmarshal.unpackInt8( &lower ); + nMethodId = ( nBitField & 0x3f ) << 8 | lower; + } + else + { + nMethodId = ( nBitField & 0x3f ); + } + } + + if( ! bSuccess ) + { + OSL_ENSURE ( 0 , "urp-bridge : incomplete message, skipping block" ); + break; + } + + // get new type,oid,tid + if( bType ) + { + if( ! m_unmarshal.unpackAndDestruct( + &m_pBridgeImpl->m_lastInType , getCppuType( &m_pBridgeImpl->m_lastInType ) ) ) + { + OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" ); + disposeEnvironment(); + return; + } + if( m_pBridgeImpl->m_lastInType.getTypeClass() != typelib_TypeClass_INTERFACE ) + { + OSL_ENSURE( 0 , "urp-bridge : not an interface type" ); + disposeEnvironment(); + return; + } + } + if( bOid ) + { + rtl_uString *pOid = 0; + if( m_unmarshal.unpackOid( &pOid ) ) + { + m_pBridgeImpl->m_lastInOid = pOid; + } + else + { + OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" ); + disposeEnvironment(); + return; + } + } + if( bTid ) + { + if( ! m_unmarshal.unpackTid( &(m_pBridgeImpl->m_lastInTid) ) ) + { + OSL_ENSURE( 0 , "urp-bridge : error during unpacking cached data, terminating connection" ); + disposeEnvironment(); + return; + } + } + + Job *pJob; + // do the job + if( bRequest ) + { + // get the membertypedescription + + typelib_InterfaceMethodTypeDescription *pMethodType = 0; + typelib_InterfaceAttributeTypeDescription *pAttributeType = 0; + sal_Bool bIsSetter = sal_False; + + if( getMemberTypeDescription( &pAttributeType, &pMethodType, &bIsSetter, + nMethodId, m_pBridgeImpl->m_lastInType ) ) + { + if( ! pLastRemoteI || bOid || bType ) + { + // a new interface must be retrieved + + // retrieve the interface NOW from the environment + // (avoid race conditions : oneway followed by release ) + typelib_InterfaceTypeDescription *pInterfaceType = 0; + + TYPELIB_DANGER_GET( + (typelib_TypeDescription ** ) &pInterfaceType , + m_pBridgeImpl->m_lastInType.getTypeLibType() ); + if( !pInterfaceType ) + { + delete pMultiJob; + disposeEnvironment(); + bContinue = sal_False; + break; + } + m_pEnvRemote->pExtEnv->getRegisteredInterface( + m_pEnvRemote->pExtEnv, ( void ** ) &pLastRemoteI, + m_pBridgeImpl->m_lastInOid.pData, pInterfaceType ); + TYPELIB_DANGER_RELEASE( (typelib_TypeDescription * )pInterfaceType ); + + // NOTE : Instance provider is called in the executing thread + // Otherwise, instance provider may block the bridge + } + + if( pMultiJob && ! bTid && pMethodType && pMethodType->bOneWay && ! pMultiJob->isFull()) + { + // add to the existing multijob, nothing to do here + } + else + { + // create a new multijob + if( pMultiJob ) + { + // start a previously existing multijob + pMultiJob->initiate(); + } + + pMultiJob = new ServerMultiJob( + m_pEnvRemote, m_pBridgeImpl->m_lastInTid.getHandle(), + m_pBridgeImpl, &m_unmarshal ); + } + + pMultiJob->setType( m_pBridgeImpl->m_lastInType ); + if( pMethodType ) + pMultiJob->setMethodType( pMethodType , REMOTE_RELEASE_METHOD_INDEX == nMethodId); + else if( pAttributeType ) + pMultiJob->setAttributeType( pAttributeType, bIsSetter ); + + if( pLastRemoteI ) + pMultiJob->setInterface( pLastRemoteI ); + else + pMultiJob->setOid( m_pBridgeImpl->m_lastInOid ); + +#ifdef BRIDGES_URP_PROT + bIsOneWay = pMethodType && pMethodType->bOneWay; + sMemberName = pMethodType ? + pMethodType->aBase.pMemberName : + pAttributeType->aBase.pMemberName; +#endif + } + else + { + delete pMultiJob; + disposeEnvironment(); + bContinue = sal_False; + break; + } + pJob = pMultiJob; + } + else + { + if( pMultiJob ) + { + pMultiJob->initiate(); + pMultiJob = 0; + } + if( pLastRemoteI ) + { + pLastRemoteI->release( pLastRemoteI ); + pLastRemoteI = 0; + } + ClientJob *pClientJob = + m_pBridgeImpl->m_clientJobContainer.remove( m_pBridgeImpl->m_lastInTid ); + OSL_ASSERT( pClientJob ); + pClientJob->m_bExceptionOccured = bExceptionOccured; + + pJob = pClientJob; + pJob->setThreadId( m_pBridgeImpl->m_lastInTid.getHandle() ); + pJob->setUnmarshal( &m_unmarshal ); +#ifdef BRIDGES_URP_PROT + sMemberName = pClientJob->m_pMethodType ? + pClientJob->m_pMethodType->aBase.pMemberName : + pClientJob->m_pAttributeType->aBase.pMemberName; +#endif + } + +#ifdef BRIDGES_URP_PROT + sal_uInt32 nLogHeader = m_unmarshal.getPos(); +#endif + + if( ! pJob->extract( ) ) + { + // severe error during extracting, dispose + delete pJob; + disposeEnvironment(); + bContinue = sal_False; + break; + } + +#ifdef BRIDGES_URP_PROT + { + if( bRequest ) + { + urp_logServingRequest( + m_pBridgeImpl, m_unmarshal.getPos() - nLogStart, + m_unmarshal.getPos() - nLogHeader, + !bIsOneWay, + sMemberName ); + } + else + { + urp_logGettingReply( + m_pBridgeImpl, m_unmarshal.getPos() - nLogStart, + m_unmarshal.getPos() - nLogHeader, sMemberName ); + } + } +#endif + if( ! pMultiJob ) + { + pJob->initiate(); + } + } // end while( !m_unmarshal.finished() ) + + if( pLastRemoteI ) + pLastRemoteI->release( pLastRemoteI ); + + if( pMultiJob ) + { + pMultiJob->initiate(); + } + + m_unmarshal.restart(); + } + + if( m_pConnection ) + { + m_pConnection->release( m_pConnection ); + m_pConnection = 0; + } +} +} diff --git a/bridges/source/remote/urp/urp_reader.hxx b/bridges/source/remote/urp/urp_reader.hxx new file mode 100644 index 000000000000..608327447f73 --- /dev/null +++ b/bridges/source/remote/urp/urp_reader.hxx @@ -0,0 +1,102 @@ +/************************************************************************* + * + * $RCSfile: urp_reader.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <vos/thread.hxx> + +#include "urp_unmarshal.hxx" + +struct remote_Connection; +typedef struct _uno_Environment uno_Environment; + +namespace bridges_urp +{ + +class OWriterThread; + +class OReaderThread : + public ::vos::OThread +{ +public: + OReaderThread( remote_Connection *pConnection , + uno_Environment *pEnvRemote, + OWriterThread *pWriterThread ); + ~OReaderThread(); + + virtual void SAL_CALL run(); + virtual void SAL_CALL onTerminated(); + + // may only be called in the callstack of this thread !!!!! + // run() -> disposeEnvironment() -> dispose() -> destroyYourself() + void destroyYourself(); + +private: + + void disposeEnvironment(); + void throwUnmarshalException( const ::rtl::OUString &sMessage ); + + remote_Connection *m_pConnection; + uno_Environment *m_pEnvRemote; + OWriterThread *m_pWriterThread; + sal_Bool m_bDestroyMyself; + urp_BridgeImpl *m_pBridgeImpl; + Unmarshal m_unmarshal; +}; + +} diff --git a/bridges/source/remote/urp/urp_replycontainer.hxx b/bridges/source/remote/urp/urp_replycontainer.hxx new file mode 100644 index 000000000000..62aa88ce72eb --- /dev/null +++ b/bridges/source/remote/urp/urp_replycontainer.hxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * $RCSfile: urp_replycontainer.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <hash_map> +#include <list> + +#include <osl/mutex.hxx> +#include <osl/diagnose.h> + +#include "urp_threadid.hxx" + +namespace bridges_urp +{ + + class ClientJob; + typedef ::std::hash_map< ::rtl::ByteSequence , + ::std::list < ClientJob * > , + HashThreadId , + EqualThreadId > Id2ClientJobStackMap; + + class urp_ClientJobContainer + { + public: + void add( const ::rtl::ByteSequence &id , ClientJob *p ) + { + ::osl::MutexGuard guard( m_mutex ); + m_map[id].push_back( p ); + } + + ClientJob *remove( const ::rtl::ByteSequence & id ) + { + ::osl::MutexGuard guard( m_mutex ); + Id2ClientJobStackMap::iterator ii = m_map.find( id ); + + OSL_ASSERT( ii != m_map.end() ); + + ClientJob *p = (*ii).second.back(); + (*ii).second.pop_back(); + if( (*ii).second.empty() ) + { + m_map.erase( ii ); + } + return p; + } + + private: + ::osl::Mutex m_mutex; + Id2ClientJobStackMap m_map; + }; + + + +} diff --git a/bridges/source/remote/urp/urp_threadid.hxx b/bridges/source/remote/urp/urp_threadid.hxx new file mode 100644 index 000000000000..9f149aedf618 --- /dev/null +++ b/bridges/source/remote/urp/urp_threadid.hxx @@ -0,0 +1,90 @@ +/************************************************************************* + * + * $RCSfile: urp_threadid.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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): _______________________________________ + * + * + ************************************************************************/ +#ifndef _URP_THREADID_HXX_ +#define _URP_THREADID_HXX_ + +#include <sal/types.h> +#include <rtl/byteseq.hxx> + +namespace bridges_urp +{ + + struct EqualThreadId + { + sal_Int32 operator () ( const ::rtl::ByteSequence &a , const ::rtl::ByteSequence &b ) const + { + return a == b; + } + }; + + struct HashThreadId + { + sal_Int32 operator () ( const ::rtl::ByteSequence &a ) const + { + if( a.getLength() >= 4 ) + { + return *(sal_Int32*) a.getConstArray(); + } + return 0; + } + }; +} +#endif diff --git a/bridges/source/remote/urp/urp_unmarshal.cxx b/bridges/source/remote/urp/urp_unmarshal.cxx new file mode 100644 index 000000000000..d5c2c95e12a6 --- /dev/null +++ b/bridges/source/remote/urp/urp_unmarshal.cxx @@ -0,0 +1,529 @@ +/************************************************************************* + * + * $RCSfile: urp_unmarshal.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:50 $ + * + * 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 <string.h> + +#include <osl/diagnose.h> + +#include <rtl/alloc.h> + +#include <uno/data.h> +#include <uno/any2.h> +#include <uno/sequence2.h> + +#include <com/sun/star/uno/Any.hxx> + +#include "urp_unmarshal.hxx" +#include "urp_bridgeimpl.hxx" + + +using namespace ::rtl; +using namespace ::com::sun::star::uno; + +namespace bridges_urp +{ +static int g_nDetectLittleEndian = 1; +char g_bSystemIsLittleEndian = ((char*)&g_nDetectLittleEndian)[0]; + + +Unmarshal::Unmarshal( struct urp_BridgeImpl *pBridgeImpl, + uno_Environment *pEnvRemote, + remote_createStubFunc callback ) : + m_pBridgeImpl( pBridgeImpl ), + m_pEnvRemote( pEnvRemote ), + m_callback( callback ), + m_nBufferSize( 4096 ), + m_base( (sal_Int8*) rtl_allocateMemory( m_nBufferSize ) ), + m_pos( m_base ), + m_nLength( 0 ) +{ +} + +Unmarshal::~Unmarshal() +{ + rtl_freeMemory( m_base ); +} + +sal_Bool Unmarshal::setSize( sal_Int32 nSize ) +{ + if( nSize > m_nBufferSize ) + { + m_nBufferSize = nSize; + m_base = (sal_Int8 * ) rtl_reallocateMemory( (sal_uInt8*) m_base , m_nBufferSize ); + m_pos = m_base; + } + m_nLength = nSize; + return ( 0 != m_base ); +} + + +// sal_Bool Unmarshal::unpack( void *pDest, const ::com::sun::star::uno::Type &rType) +// { +// typelib_TypeDescription * pDataTD = 0; +// TYPELIB_DANGER_GET( &pDataTD, rType.getTypeLibType() ); +// sal_Bool b = unpack( pDest, pDataTD ); +// TYPELIB_DANGER_RELEASE( pDataTD ); +// return b; +// } + +sal_Bool Unmarshal::unpackAndDestruct( void *pDest, const ::com::sun::star::uno::Type &rType) +{ + typelib_TypeDescription * pDataTD = 0; + TYPELIB_DANGER_GET( &pDataTD, rType.getTypeLibType() ); + uno_destructData( pDest , pDataTD , 0 ); + sal_Bool b = unpack( pDest, pDataTD ); + TYPELIB_DANGER_RELEASE( pDataTD ); + return b; +} + +sal_Bool Unmarshal::unpackAndDestruct( void *pDest, typelib_TypeDescription *pType) +{ + uno_destructData( pDest , pType , 0 ); + return unpack( pDest, pType ); +} + + + +// special unpacks +sal_Bool Unmarshal::unpackTid( ::rtl::ByteSequence *pId ) +{ + sal_Int32 nSize; + sal_Bool bReturn = unpackCompressedSize( &nSize ); + if( bReturn ) + { + if( nSize ) + { + *pId = ByteSequence( m_pos , nSize ); + m_pos += nSize; + sal_uInt16 nIndex; + bReturn = unpackInt16( &nIndex ); + if( nIndex < m_pBridgeImpl->m_nCacheSize ) + { + m_pBridgeImpl->m_pTidIn[nIndex] = *pId; + } + else if( 0xffff != nIndex ) + { + bReturn = sal_False; + *pId = ByteSequence(); + OSL_ENSURE( 0 , "unknown thread id" ); + } + } + else + { + sal_uInt16 nIndex; + bReturn = unpackInt16( &nIndex ); + if( nIndex < m_pBridgeImpl->m_nCacheSize ) + { + *pId = m_pBridgeImpl->m_pTidIn[nIndex]; + } + else + { + bReturn = sal_False; + *pId = ByteSequence(); + OSL_ENSURE( 0 , "unknown thread id" ); + } + } + } + return bReturn; +} + +sal_Bool Unmarshal::unpackOid( rtl_uString **ppOid ) +{ + sal_Bool bReturn = sal_True; + sal_uInt16 nCacheIndex; + + bReturn = bReturn && unpackString( ppOid ); + bReturn = bReturn && unpackInt16( &nCacheIndex ); + + if( bReturn && + ! ( 0xffff == nCacheIndex && 0 == (*ppOid)->length ) /* null reference */ ) + { + if( (*ppOid)->length ) + { + // new unknown reference + if( 0xffff != nCacheIndex ) + { + // oid should be cached ? + if( nCacheIndex < m_pBridgeImpl->m_nCacheSize ) + { + m_pBridgeImpl->m_pOidIn[nCacheIndex] = *ppOid; + } + else + { + bReturn = sal_False; + } + } + } + else + { + // reference in cache ! + if( nCacheIndex < m_pBridgeImpl->m_nCacheSize ) + { + rtl_uString_assign( ppOid , m_pBridgeImpl->m_pOidIn[nCacheIndex].pData ); + } + else + { + bReturn = sal_False; + } + } + } + + return bReturn; +} + +template < class t > +inline sal_Int32 convertFromPackedInt( t* pTarget , const sal_uInt8 *pSource , sal_Int32 nMaxToGo ) +{ + *pTarget = 0; + sal_Int32 i = 0; + do + { + *pTarget |= ( ( sal_Int64) (pSource[i] & 0x7f) ) << ( i * 7 ); + i ++; + } while ( i < nMaxToGo && (pSource[i-1] & 0x80) ); + + return i; +} + + +sal_Bool Unmarshal::unpackType( void *pDest ) +{ + *(typelib_TypeDescriptionReference **) pDest = 0; + + sal_uInt8 nTypeClass; + sal_Bool bReturn = unpackInt8( &nTypeClass ); + + Type type; + if( bReturn ) + { + if( nTypeClass <= 14 /* any */ ) + { + switch( nTypeClass ) + { + case typelib_TypeClass_VOID: + { + type = getVoidCppuType( ); + break; + } + case typelib_TypeClass_CHAR: + { + type = getCharCppuType( ); + break; + } + case typelib_TypeClass_BOOLEAN: + { + type = getBooleanCppuType(); + break; + } + case typelib_TypeClass_BYTE: + { + type = getCppuType( (sal_Int8 *) 0); + break; + } + case typelib_TypeClass_SHORT: + { + type = getCppuType( ( sal_Int16 *)0 ); + break; + } + case typelib_TypeClass_UNSIGNED_SHORT: + { + type = getCppuType( (sal_uInt16 *)0 ); + break; + } + case typelib_TypeClass_LONG: + { + type = getCppuType( ( sal_Int32 *) 0 ); + break; + } + case typelib_TypeClass_UNSIGNED_LONG: + { + type = getCppuType( ( sal_uInt32 *) 0 ); + break; + } + case typelib_TypeClass_HYPER: + { + type = getCppuType( ( sal_Int64 *) 0 ); + break; + } + case typelib_TypeClass_UNSIGNED_HYPER: + { + type = getCppuType( ( sal_uInt64 *) 0 ); + break; + } + case typelib_TypeClass_FLOAT: + { + type = getCppuType( ( float *) 0 ); + break; + } + case typelib_TypeClass_DOUBLE: + { + type = getCppuType( (double*) 0 ); + break; + } + case typelib_TypeClass_STRING: + { + type = getCppuType( (OUString *) 0 ); + break; + } + case typelib_TypeClass_TYPE: + { + type = getCppuType( (Type *) 0 ); + break; + } + case typelib_TypeClass_ANY: + { + type = getCppuType( (Any *) 0 ); + break; + } + } + } + else + { + sal_uInt16 nCacheIndex; + bReturn = bReturn && unpackInt16( &nCacheIndex ); + + if( bReturn ) + { + if( nTypeClass & 0x80 ) + { + // new type + rtl_uString *pString = 0; + bReturn = bReturn && unpackString( &pString ); + if( bReturn ) + { + type = Type( (enum TypeClass )(nTypeClass & 0x7f) , pString ); + if( nCacheIndex != 0xffff ) + { + if( nCacheIndex < m_pBridgeImpl->m_nCacheSize ) + { + m_pBridgeImpl->m_pTypeIn[nCacheIndex] = type; + } + else + { + bReturn = sal_False; + } + } + } + if( pString ) + { + rtl_uString_release( pString ); + } + } + else + { + if( nCacheIndex < m_pBridgeImpl->m_nCacheSize ) + { + type = m_pBridgeImpl->m_pTypeIn[nCacheIndex]; + } + else + { + bReturn = sal_False; + } + } + } + } + } + *(typelib_TypeDescriptionReference**)pDest = type.getTypeLibType(); + typelib_typedescriptionreference_acquire( *(typelib_TypeDescriptionReference**)pDest ); + return bReturn; +} + +sal_Bool Unmarshal::unpackAny( void *pDest ) +{ + uno_Any *pAny = ( uno_Any * )pDest; + + pAny->pType = 0; + // Type is acquired with typelib_typedescription_acquire + + sal_Bool bReturn = unpackType( &(pAny->pType) ); + + typelib_TypeDescription *pType = 0; + if( bReturn && pAny->pType ) + { + typelib_typedescriptionreference_getDescription( &pType , pAny->pType ); + + if( pType ) + { + pAny->pData = rtl_allocateMemory( pType->nSize ); + bReturn = unpack( pAny->pData , pType ); + } + } + + if( pType ) + { + typelib_typedescription_release( pType ); + } + else + { + pAny->pData = 0; + Type type; // void + pAny->pType = type.getTypeLibType(); + typelib_typedescriptionreference_acquire( pAny->pType ); + + bReturn = sal_False; + } + return bReturn; +} + + +sal_Bool Unmarshal::unpackRecursive( void *pDest , typelib_TypeDescription *pType ) +{ + sal_Bool bReturn = sal_True; + + switch( pType->eTypeClass ) + { + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + { + typelib_CompoundTypeDescription * pCompType = + (typelib_CompoundTypeDescription *)pType; + + if (pCompType->pBaseTypeDescription) + { + bReturn = + unpack( pDest , (typelib_TypeDescription * ) pCompType->pBaseTypeDescription ); + } + + // then construct members + typelib_TypeDescriptionReference ** ppTypeRefs = pCompType->ppTypeRefs; + sal_Int32 * pMemberOffsets = pCompType->pMemberOffsets; + sal_Int32 nDescr = pCompType->nMembers; + + // at least assume 1 byte per member + bReturn = bReturn && ! checkOverflow( nDescr * 1 ); + for ( sal_Int32 nPos = 0; nPos < nDescr; ++nPos ) + { + typelib_TypeDescription * pMemberType = 0; + TYPELIB_DANGER_GET( &pMemberType, ppTypeRefs[nPos] ); + // Even if bReturn is false, all values must be default constructed ! + if( bReturn ) + { + bReturn = unpack( (char*)pDest + pMemberOffsets[nPos] , pMemberType ) && bReturn; + } + else + { + uno_constructData( (char*)pDest + pMemberOffsets[nPos] , pMemberType ); + } + TYPELIB_DANGER_RELEASE( pMemberType ); + } + break; + } + case typelib_TypeClass_SEQUENCE: + { + sal_Int32 nLen; + bReturn = unpackCompressedSize( &nLen ); + + // urp protocol does not allow to use the elementsize as a guess, if enough data + // is available. However, at least one byte per member must be within the message + bReturn = bReturn && ! checkOverflow( 1 * nLen ); + uno_Sequence *pSequence = 0; + if( nLen && bReturn ) + { + typelib_TypeDescriptionReference * pETRef = + ((typelib_IndirectTypeDescription *)pType)->pType; + + typelib_TypeDescription * pET = 0; + typelib_typedescriptionreference_getDescription( &pET , pETRef ); + + if( pET ) + { + sal_Int32 nElementSize = pET->nSize; + + pSequence = (uno_Sequence *)rtl_allocateMemory( + SAL_SEQUENCE_HEADER_SIZE + nElementSize * nLen ); + pSequence->nRefCount = 1; + pSequence->nElements = nLen; + + if( typelib_TypeClass_BYTE == pET->eTypeClass ) + { + memcpy( pSequence->elements , m_pos , nLen ); + m_pos += nLen; + } + else + { + for( sal_Int32 i = 0 ; i < nLen ; i ++ ) + { + bReturn = unpack( ((char*)pSequence->elements)+ i*nElementSize,pET ) && bReturn; + } + } + typelib_typedescription_release( pET ); + } + else + { + bReturn = sal_False; + uno_constructData( &pSequence , pType ); + } + } + else + { + uno_constructData( &pSequence , pType ); + } + + *((uno_Sequence **)pDest) = pSequence; + break; + } + default: + OSL_ASSERT( 0 ); + } + return bReturn; +} + +} + diff --git a/bridges/source/remote/urp/urp_unmarshal.hxx b/bridges/source/remote/urp/urp_unmarshal.hxx new file mode 100644 index 000000000000..b0242814a241 --- /dev/null +++ b/bridges/source/remote/urp/urp_unmarshal.hxx @@ -0,0 +1,392 @@ +/************************************************************************* + * + * $RCSfile: urp_unmarshal.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _URP_UNMARSHAL_HXX_ +#define _URP_UNMARSHAL_HXX_ + +#include <rtl/byteseq.hxx> + +#include <bridges/remote/context.h> + +#include <com/sun/star/uno/Type.hxx> + +typedef struct _uno_Environment uno_Environment; +struct remote_Interface; + +namespace bridges_urp +{ + + extern char g_bSystemIsLittleEndian; +class ThreadId; +struct urp_BridgeImpl; +class Unmarshal +{ +public: + Unmarshal( + struct urp_BridgeImpl *, + uno_Environment *pEnvRemote, + remote_createStubFunc callback ); + ~Unmarshal(); + + sal_Bool unpackAndDestruct( void *pDest , const ::com::sun::star::uno::Type &rType ); + sal_Bool unpackAndDestruct( void *pDest , typelib_TypeDescription *pType ); + sal_Bool unpackRecursive( void *pDest , typelib_TypeDescription *pType ); + sal_Bool finished() + { return m_base + m_nLength == m_pos; } + sal_uInt32 getPos() + { return (sal_uInt32 ) (m_pos - m_base); } + + sal_Bool setSize( sal_Int32 nSize ); + + inline sal_Bool unpackCompressedSize( sal_Int32 *pData ); + inline sal_Bool unpack( void *pDest, typelib_TypeDescription *pType ); + inline sal_Bool unpackInt8( void *pDest ); + inline sal_Bool unpackString( void *pDest ); + inline sal_Bool unpackInt16( void *pDest ); + inline sal_Bool unpackInt32( void *pDest ); + sal_Bool unpackType( void *pDest ); + + sal_Bool unpackAny( void *pDest ); + sal_Bool unpackOid( rtl_uString **ppOid ); + sal_Bool unpackTid( ::rtl::ByteSequence *pId ); + + void restart() + { m_pos = m_base; } + + sal_Int8 *getBuffer() + { return m_base; } + inline sal_Bool isSystemLittleEndian() + { return g_bSystemIsLittleEndian; } + +private: + inline sal_Bool checkOverflow( sal_Int32 nNextMem ); + + sal_Int32 m_nBufferSize; + sal_Int8 *m_base; + sal_Int8 *m_pos; + + sal_Int32 m_nLength; + + remote_createStubFunc m_callback; + uno_Environment *m_pEnvRemote; + urp_BridgeImpl *m_pBridgeImpl; +}; + +inline sal_Bool Unmarshal::checkOverflow( sal_Int32 nNextMem ) +{ + return nNextMem < 0 || + (((sal_uInt32)( m_pos - m_base )) + nNextMem ) > m_nLength; +} + + +inline sal_Bool Unmarshal::unpackInt8( void *pDest ) +{ + sal_Bool bReturn = ! checkOverflow( 1 ); + if( bReturn ) + { + *((sal_Int8*)pDest ) = *m_pos; + m_pos++; + } + else + { + *((sal_Int8*)pDest ) = 0; + } + return bReturn; +} + +inline sal_Bool Unmarshal::unpackInt32( void *pDest ) +{ + sal_uInt32 *p = ( sal_uInt32 * ) pDest; + sal_Bool bReturn = ! checkOverflow(4); + if( bReturn ) + { + if( isSystemLittleEndian() ) + { + ((sal_Int8*) p )[3] = m_pos[0]; + ((sal_Int8*) p )[2] = m_pos[1]; + ((sal_Int8*) p )[1] = m_pos[2]; + ((sal_Int8*) p )[0] = m_pos[3]; + } + else + { + ((sal_Int8*) p )[3] = m_pos[3]; + ((sal_Int8*) p )[2] = m_pos[2]; + ((sal_Int8*) p )[1] = m_pos[1]; + ((sal_Int8*) p )[0] = m_pos[0]; + } + m_pos += 4; + } + else + { + *p = 0; + } + return bReturn; +} + +inline sal_Bool Unmarshal::unpackInt16( void *pDest ) +{ + sal_uInt16 *p = ( sal_uInt16 * ) pDest; + + sal_Bool bReturn = ! checkOverflow( 2 ); + if( bReturn ) + { + if( isSystemLittleEndian() ) + { + ((sal_Int8*) p )[1] = m_pos[0]; + ((sal_Int8*) p )[0] = m_pos[1]; + } + else + { + ((sal_Int8*) p )[1] = m_pos[1]; + ((sal_Int8*) p )[0] = m_pos[0]; + } + m_pos ++; + m_pos ++; + } + else + { + *p = 0; + } + return bReturn; +} + +inline sal_Bool Unmarshal::unpackString( void *pDest ) +{ + sal_Int32 nLength; + sal_Bool bReturn = unpackCompressedSize( &nLength ); + + bReturn = bReturn && ! checkOverflow( nLength ); + if( bReturn ) + { + *(rtl_uString **) pDest = 0; + rtl_string2UString( (rtl_uString**) pDest, (const sal_Char * )m_pos , nLength, + RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS ); + m_pos += nLength; + } + else + { + *(rtl_uString ** ) pDest = 0; + rtl_uString_new( (rtl_uString **) pDest ); + } + return bReturn; +} + + +sal_Bool Unmarshal::unpackCompressedSize( sal_Int32 *pData ) +{ + sal_uInt8 n8Size; + sal_Bool bReturn = unpackInt8( &n8Size ); + if( bReturn ) + { + if( n8Size == 0xff ) + { + unpackInt32( pData ); + } + else + { + *pData = (sal_Int32 ) n8Size; + } + } + return bReturn; +} + +inline sal_Bool Unmarshal::unpack( void *pDest , typelib_TypeDescription *pType ) +{ + sal_Bool bReturn = sal_True; + switch( pType->eTypeClass ) + { + case typelib_TypeClass_VOID: + // do nothing + break; + case typelib_TypeClass_BYTE: + { + bReturn = unpackInt8( pDest ); + break; + } + case typelib_TypeClass_BOOLEAN: + { + bReturn = ! checkOverflow( 1 ); + if( bReturn ) + { + *((sal_Bool*)pDest) = (sal_Bool ) ( *m_pos); + m_pos ++; + } + else + { + *((sal_Bool*)pDest) = 0; + } + break; + } + + case typelib_TypeClass_CHAR: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + { + unpackInt16( pDest ); + break; + } + case typelib_TypeClass_FLOAT: + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + { + bReturn = unpackInt32( pDest ); + break; + } + case typelib_TypeClass_DOUBLE: + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + { + sal_uInt64 *p = ( sal_uInt64 * ) pDest; + *p = 0; + bReturn = ! checkOverflow( 8 ); + if( bReturn ) + { + if( isSystemLittleEndian() ) + { + ((sal_Int8*) p )[7] = m_pos[0]; + ((sal_Int8*) p )[6] = m_pos[1]; + ((sal_Int8*) p )[5] = m_pos[2]; + ((sal_Int8*) p )[4] = m_pos[3]; + ((sal_Int8*) p )[3] = m_pos[4]; + ((sal_Int8*) p )[2] = m_pos[5]; + ((sal_Int8*) p )[1] = m_pos[6]; + ((sal_Int8*) p )[0] = m_pos[7]; + } + else + { + ((sal_Int8*) p )[0] = m_pos[0]; + ((sal_Int8*) p )[1] = m_pos[1]; + ((sal_Int8*) p )[2] = m_pos[2]; + ((sal_Int8*) p )[3] = m_pos[3]; + ((sal_Int8*) p )[4] = m_pos[4]; + ((sal_Int8*) p )[5] = m_pos[5]; + ((sal_Int8*) p )[6] = m_pos[6]; + ((sal_Int8*) p )[7] = m_pos[7]; + } + m_pos += 8; + } + break; + } + case typelib_TypeClass_STRING: + { + unpackString( pDest ); + break; + } + case typelib_TypeClass_ANY: + { + bReturn = unpackAny( pDest ); + break; + } + case typelib_TypeClass_ENUM: + { + bReturn = unpackCompressedSize( (sal_Int32 *) pDest ); + break; + } + case typelib_TypeClass_INTERFACE: + { + *(remote_Interface**)pDest = 0; + + rtl_uString *pString = 0; + bReturn = unpackOid( &pString ) && bReturn; + + if( bReturn && pString && pString->length ) + { + m_callback( (remote_Interface**) pDest , + pString, + pType->pWeakRef , + m_pEnvRemote ); + } + if( pString ) + { + rtl_uString_release( pString ); + } + break; + } + case typelib_TypeClass_TYPE: + { + bReturn = unpackType( pDest ); + break; + } + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_EXCEPTION: + case typelib_TypeClass_SEQUENCE: + { + bReturn = unpackRecursive( pDest, pType ); + break; + } + + case typelib_TypeClass_UNION: + case typelib_TypeClass_ARRAY: + case typelib_TypeClass_SERVICE: + case typelib_TypeClass_MODULE: + case typelib_TypeClass_INTERFACE_METHOD: + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + case typelib_TypeClass_UNKNOWN: + default: + OSL_ASSERT( 0 ); + } + + + return bReturn; +} + +} + +#endif diff --git a/bridges/source/remote/urp/urp_writer.cxx b/bridges/source/remote/urp/urp_writer.cxx new file mode 100644 index 000000000000..247083b66912 --- /dev/null +++ b/bridges/source/remote/urp/urp_writer.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * $RCSfile: urp_writer.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <assert.h> +#include <stdio.h> + +#include <vos/thread.hxx> + +#include <osl/mutex.hxx> +#include <osl/conditn.h> + +#include <bridges/remote/connection.h> +#include <bridges/remote/remote.hxx> + +#include <com/sun/star/uno/Sequence.hxx> + +#include <bridges/remote/counter.hxx> + +#include "urp_writer.hxx" +#include "urp_bridgeimpl.hxx" +#include "urp_marshal.hxx" + +#ifdef DEBUG +static MyCounter thisCounter( "DEBUG : WriterThread" ); +#endif + +using namespace ::osl; + +namespace bridges_urp { + +OWriterThread::OWriterThread( remote_Connection *pConnection, urp_BridgeImpl *pBridgeImpl) : + m_pConnection( pConnection ), + m_bAbort( sal_False ), + m_pBridgeImpl( pBridgeImpl ) +{ + m_oslCondition = osl_createCondition(); + osl_resetCondition( m_oslCondition ); + m_pConnection->acquire( m_pConnection ); + +#ifdef DEBUG + thisCounter.acquire(); +#endif +} + +OWriterThread::~OWriterThread() +{ + osl_destroyCondition( m_oslCondition ); + m_pConnection->release( m_pConnection ); +#ifdef DEBUG + thisCounter.release(); +#endif +} + + +// touch is called with locked m_marshalingMutex +void OWriterThread::touch( sal_Bool bImmediately ) +{ + if( bImmediately || m_pBridgeImpl->m_blockMarshaler.getPos() > m_pBridgeImpl->m_nFlushBlockSize ) + { + write(); + } +} + + +void OWriterThread::abort() +{ + m_bAbort = sal_True; + osl_setCondition( m_oslCondition ); + join(); +} + + +// must be called with locked marshaling mutex +void OWriterThread::write() +{ + if( ! m_pBridgeImpl->m_blockMarshaler.empty() ) + { + m_pBridgeImpl->m_blockMarshaler.finish(); + + sal_Int32 nLength = m_pBridgeImpl->m_blockMarshaler.getSize(); + sal_Int8 *pBuf = m_pBridgeImpl->m_blockMarshaler.getBuffer(); + + if( nLength != m_pConnection->write( m_pConnection, pBuf, nLength )) + { + m_pBridgeImpl->m_blockMarshaler.restart(); + return; + } + m_pConnection->flush( m_pConnection ); + m_pBridgeImpl->m_blockMarshaler.restart(); + } +} + +void OWriterThread::sendEmptyMessage() +{ + // must be called with locked marshaling mutex + sal_Int8 n = 0; + if( m_pConnection ) + { + m_pConnection->write( m_pConnection , &n , 1 ); + } +} + +void OWriterThread::run() +{ + while( sal_True ) + { + // Wait for some work to do +// osl_waitCondition( m_oslCondition , 0 ); +// if( m_bAbort ) +// { +// break; +// } + +// if( m_bWaitForTimeout ) +// { + // wait for timeout +// printf( "Waiting for timeout ....\n" ); + TimeValue value = { 0 , 1000 * m_pBridgeImpl->m_nTimeoutMUSEC }; + osl_resetCondition( m_oslCondition ); + osl_waitCondition( m_oslCondition , &value ); +// } + + { + // write to the socket + MutexGuard guard( m_pBridgeImpl->m_marshalingMutex ); + m_bWaitForTimeout = sal_False; + if( ! m_pBridgeImpl->m_blockMarshaler.empty() ) + { +// printf( "Sending with timeout\n" ); + write(); + } + osl_resetCondition( m_oslCondition ); + } + if( m_bAbort ) + { + break; + } + + } +} + + +} + diff --git a/bridges/source/remote/urp/urp_writer.hxx b/bridges/source/remote/urp/urp_writer.hxx new file mode 100644 index 000000000000..1916a67554eb --- /dev/null +++ b/bridges/source/remote/urp/urp_writer.hxx @@ -0,0 +1,97 @@ +/************************************************************************* + * + * $RCSfile: urp_writer.hxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <osl/conditn.h> +#include <vos/thread.hxx> + +struct remote_Connection; + +namespace bridges_urp +{ + + struct urp_BridgeImpl; + class OWriterThread : + public ::vos::OThread + { + public: + OWriterThread( remote_Connection *pConnection, + urp_BridgeImpl *m_pBridgeImpl); + ~OWriterThread( ); + + virtual void SAL_CALL run(); + + void touch( sal_Bool bImmediately ); + void sendEmptyMessage(); + + void abort(); + + private: + void write(); + oslCondition m_oslCondition; + + sal_Bool m_bAbort; + sal_Bool m_bWaitForTimeout; + remote_Connection *m_pConnection; + urp_BridgeImpl *m_pBridgeImpl; + }; + + +} + diff --git a/bridges/test/makefile.mk b/bridges/test/makefile.mk new file mode 100644 index 000000000000..6773ce71c746 --- /dev/null +++ b/bridges/test/makefile.mk @@ -0,0 +1,279 @@ +#************************************************************************* +# +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ +# +# The Contents of this file are made available subject to the terms of +# either of the following licenses +# +# - GNU Lesser General Public License Version 2.1 +# - Sun Industry Standards Source License Version 1.1 +# +# Sun Microsystems Inc., October, 2000 +# +# GNU Lesser General Public License Version 2.1 +# ============================================= +# Copyright 2000 by Sun Microsystems, Inc. +# 901 San Antonio Road, Palo Alto, CA 94303, USA +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License version 2.1, as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +# +# Sun Industry Standards Source License Version 1.1 +# ================================================= +# The contents of this file are subject to the Sun Industry Standards +# Source License Version 1.1 (the "License"); You may not use this file +# except in compliance with the License. You may obtain a copy of the +# License at http://www.openoffice.org/license.html. +# +# Software provided under this License is provided on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +# See the License for the specific provisions governing your rights and +# obligations concerning the Software. +# +# The Initial Developer of the Original Code is: Sun Microsystems, Inc. +# +# Copyright: 2000 by Sun Microsystems, Inc. +# +# All Rights Reserved. +# +# Contributor(s): _______________________________________ +# +# +# +#************************************************************************* + +PRJ=.. + +PRJNAME=bridges +TARGET=test +LIBTARGET=NO +TARGETTYPE=CUI +ENABLE_EXCEPTIONS=TRUE +NO_BSYMBOLIC=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : svpre.mk +.INCLUDE : settings.mk +.INCLUDE : sv.mk + +# --- Files -------------------------------------------------------- +ALLIDLFILES = test_bridge.idl +#CPPUMAKERFLAGS += -C + + +UNOUCRDEP=$(SOLARBINDIR)$/applicat.rdb +UNOUCRRDB=$(SOLARBINDIR)$/applicat.rdb $(BIN)$/test.rdb + +# output directory (one dir for each project) +UNOUCROUT=$(OUT)$/inc + +# adding to inludeoath +INCPRE+=$(UNOUCROUT) +CFLAGS += -I..$/source$/remote$/urp + +UNOTYPES = \ + com.sun.star.uno.XWeak\ + com.sun.star.uno.XNamingService\ + com.sun.star.uno.XAggregation \ + com.sun.star.uno.TypeClass\ + com.sun.star.io.XInputStream\ + com.sun.star.io.XOutputStream\ + com.sun.star.lang.XInitialization \ + com.sun.star.lang.XSingleServiceFactory \ + com.sun.star.lang.XMultiServiceFactory \ + com.sun.star.lang.XTypeProvider \ + com.sun.star.frame.XComponentLoader\ + com.sun.star.registry.XSimpleRegistry \ + com.sun.star.loader.XImplementationLoader \ + com.sun.star.registry.XImplementationRegistration \ + com.sun.star.corba.giop.TargetAddress \ + com.sun.star.corba.giop.TargetAddressGroup \ + com.sun.star.lang.XComponent \ + com.sun.star.bridge.XBridgeFactory\ + com.sun.star.connection.XAcceptor\ + com.sun.star.connection.XConnector\ + com.sun.star.beans.Property\ + com.sun.star.corba.giop.RequestHeader_1_2\ + com.sun.star.container.XSet\ + com.sun.star.text.XTextDocument\ + com.sun.star.lang.XServiceInfo\ + test.XTestFactory \ + com.sun.star.test.performance.XPerformanceTest \ + com.sun.star.lang.XMain + +#UNOTYPES= com.sun.star.corba.giop.MsgType_1_1 +#UNOTYPES= com.sun.star.uno.XInterface \ +# com.sun.star.uno.TypeClass \ +# com.sun.star.corba.CorbaString8 +#com.sun.star.corba.giop.RequestHeader_1_1 + +JARFILES = jurt.jar sandbox.jar unoil.jar + + + +# GENJAVACLASSFILES = \ +# $(CLASSDIR)$/test$/TestTypes.class \ +# $(CLASSDIR)$/test$/TestBridgeException.class \ +# $(CLASSDIR)$/test$/XCallMe.class \ +# $(CLASSDIR)$/test$/XInterfaceTest.class \ +# $(CLASSDIR)$/test$/XTestFactory.class \ + + +# JAVACLASSFILES= \ +# $(CLASSDIR)$/testclient.class + + + +# TYPES={$(subst,.class, $(subst,$/,. $(subst,$(CLASSDIR)$/,-T $(GENJAVACLASSFILES))))} +# GENJAVAFILES = {$(subst,.class,.java $(subst,$/class, $(GENJAVACLASSFILES)))} +# JAVAFILES= $(subst,$(CLASSDIR)$/, $(subst,.class,.java $(JAVACLASSFILES))) $(GENJAVAFILES) + + +OBJFILES= \ + $(OBJ)$/testserver.obj \ + $(OBJ)$/testclient.obj \ + $(OBJ)$/testcomp.obj \ + $(OBJ)$/testsameprocess.obj \ + $(OBJ)$/testoffice.obj + + +# APP1TARGET= testmarshal +# APP1OBJS= $(OBJ)$/testmarshal.obj \ +# $(SLO)$/urp_marshal.obj\ +# $(SLO)$/urp_unmarshal.obj \ +# $(SLO)$/urp_bridgeimpl.obj \ +# $(SLB)$/bridges_remote_static.lib + +# # $(SLO)$/marshal.obj\ +# # $(SLO)$/unmarshal.obj\ + +# .IF "$(OS)" == "LINUX" +# APP1STDLIBS+= -lstdc++ +# .ENDIF + +#APP1LIBS+= \ +# $(SLB)$/bridges_marshal.lib +# APP1STDLIBS+= \ +# $(UNOLIB) \ +# $(CPPULIB) \ +# $(CPPUHELPERLIB) \ +# $(VOSLIB) \ +# $(SALLIB) \ +# $(LIBCIMT) + +# APP1DEF= $(MISC)$/$(APP1TARGET).def + +APP2TARGET= testserver +APP2OBJS= $(OBJ)$/testserver.obj \ + $(OBJ)$/testcomp.obj + +.IF "$(OS)" == "LINUX" +APP2STDLIBS+= -lstdc++ +.ENDIF + +APP2STDLIBS+= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) \ + $(LIBCIMT) + +#APP2DEF= $(MISC)$/$(APP2TARGET).def + +APP3TARGET= testclient +APP3OBJS= $(OBJ)$/testclient.obj \ + $(OBJ)$/testcomp.obj + +.IF "$(OS)" == "LINUX" +APP3STDLIBS+= -lstdc++ +.ENDIF + +APP3STDLIBS+= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) \ + $(LIBCIMT) +# imsci_uno.lib + +#APP3DEF= $(MISC)$/$(APP3TARGET).def + +#---------------------------------- + +APP4TARGET= testsameprocess +APP4OBJS= $(OBJ)$/testsameprocess.obj \ + $(OBJ)$/testcomp.obj + +.IF "$(OS)" == "LINUX" +APP4STDLIBS+= -lstdc++ +.ENDIF + +APP4STDLIBS+= \ + $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(VOSLIB) \ + $(SALLIB) \ + $(LIBCIMT) + +APP4DEF= $(MISC)$/$(APP4TARGET).def + +#---------------------------------- + +APP5TARGET= testoffice +APP5OBJS= $(OBJ)$/testoffice.obj \ + $(OBJ)$/testcomp.obj + +.IF "$(OS)" == "LINUX" +APP5STDLIBS+= -lstdc++ +.ENDIF + +APP5STDLIBS+= \ + $(CPPULIB) \ + $(CPPUHELPERLIB)\ + $(SALLIB) \ + $(VOSLIB)\ + $(LIBCIMT) + +APP5DEF= $(MISC)$/$(APP5TARGET).def + + +# --- Targets ------------------------------------------------------ + +#.IF "$(depend)" == "" +ALL : $(BIN)$/test.rdb \ + $(GENJAVAFILES) \ + ALLTAR + +#.ELSE +#ALL: ALLDEP +#.ENDIF + +.INCLUDE : target.mk + +$(BIN)$/test.rdb: $(ALLIDLFILES) + +unoidl -I$(PRJ) -I$(SOLARIDLDIR) -Burd -OH$(BIN) $? + +regmerge $@ /UCR $(BIN)$/{$(?:f:s/.idl/.urd/)} + touch $@ + +# $(GENJAVAFILES) : $(RDB) +# +javamaker -BUCR -O$(OUT) $(TYPES) $(UNOUCRRDB) + diff --git a/bridges/test/test_bridge.idl b/bridges/test/test_bridge.idl new file mode 100644 index 000000000000..99cfb18f00ff --- /dev/null +++ b/bridges/test/test_bridge.idl @@ -0,0 +1,119 @@ +/************************************************************************* + * + * $RCSfile: test_bridge.idl,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <com/sun/star/uno/XInterface.idl> +#include <com/sun/star/uno/Exception.idl> + +module test +{ + +struct TestTypes +{ + boolean Bool; + char Char; + byte Byte; + short Short; + unsigned short UShort; + long Long; + unsigned long ULong; + hyper Hyper; + unsigned hyper UHyper; + float Float; + double Double; +// test::TestEnum Enum; + string String; + com::sun::star::uno::XInterface Interface; + any Any; +}; + +exception TestBridgeException : com::sun::star::uno::Exception +{ + +}; + +[ uik(FE9FF5C0-95B4-11d3-9F330010-5A677293), ident("XCallMe", 1.0) ] +interface XCallMe : com::sun::star::uno::XInterface +{ + void call( [in] string s , [in] long nToDo ) raises( TestBridgeException ); + [oneway] void callOneway( [in] string s , [in] long nToDo ); + [attribute] string sAttribute; + void callAgain( [in] XCallMe callAgain, [in] long nToCall ); + TestTypes transport( [in] TestTypes types ); + [oneway] void drawLine( [in] long x1 , [in] long y1, [in] long x2, [in] long y2 ); +}; + +[uik(FE9FF5C1-95B4-11d3-9F330010-5A677293), ident("XInterfaceTest", 1.0)] +interface XInterfaceTest : com::sun::star::uno::XInterface +{ + void setIn( [in] XCallMe callback ); + void setInOut( [inout] XCallMe callback ); + void getOut( [out] XCallMe callback ); + XCallMe get(); +}; + +[ uik(FE9FF5C1-95B4-11d3-9F330010-5A677293), ident("XTestFactory", 1.0) ] +interface XTestFactory : com::sun::star::uno::XInterface +{ + XCallMe createCallMe(); + XInterfaceTest createInterfaceTest(); +}; + + +}; diff --git a/bridges/test/testclient.cxx b/bridges/test/testclient.cxx new file mode 100644 index 000000000000..74c941584097 --- /dev/null +++ b/bridges/test/testclient.cxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * $RCSfile: testclient.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <string.h> +#include <assert.h> + +#include <osl/mutex.hxx> +#include <osl/module.h> +#include <osl/thread.h> +#include <osl/conditn.h> +#include <osl/diagnose.h> + +#include <uno/mapping.hxx> + +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/connection/XConnector.hpp> + +#include <com/sun/star/bridge/XBridgeFactory.hpp> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMain.hpp> + +#include <com/sun/star/test/performance/XPerformanceTest.hpp> + +#include <cppuhelper/weak.hxx> + +#ifndef _CPPUHELPER_FACTORY_HXX_ +#include <cppuhelper/factory.hxx> +#endif + +#include <test/XTestFactory.hpp> + + +using namespace ::test; +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::connection; +using namespace ::com::sun::star::test::performance; + +#include "testcomp.h" + + +#ifdef SOLARIS +extern "C" void ChangeGlobalInit(); +#endif + + +#ifdef UNX +#define REG_PREFIX "lib" +#define DLL_POSTFIX ".so" +#else +#define REG_PREFIX "" +#define DLL_POSTFIX ".dll" +#endif + + +#include <vos/socket.hxx> + +void doPerformanceTest( const Reference < XPerformanceTest > & xBench ) +{ + printf( "not implemented\n" ); +// sal_Int32 i,nLoop = 2000; +// sal_Int32 tStart, tEnd , tEnd2; +// //------------------------------------ +// // oneway calls +// i = nLoop; +// tStart = GetTickCount(); +// while (i--) +// xBench->async(); +// tEnd = GetTickCount(); +// xBench->sync(); +// tEnd2 = GetTickCount(); +// printf( "%d %d %d\n" , nLoop, tEnd - tStart , tEnd2 -tStart ); +// // synchron calls +// i = nLoop; +// tStart = GetTickCount(); +// while (i--) +// xBench->sync(); +// tEnd = GetTickCount(); +// printf( "%d %d \n" , nLoop, tEnd - tStart ); + +} + +void testLatency( const Reference < XConnection > &r , sal_Bool bReply ) +{ + sal_Int32 nLoop = 10000; + TimeValue aStartTime, aEndTime; + osl_getSystemTime( &aStartTime ); + + sal_Int32 i; + for( i = 0 ; i < nLoop ; i++ ) + { + Sequence< sal_Int8 > s1( 200 ); + r->write( s1 ); + r->read( s1 , 12 ); + r->read( s1 , 48 ); + } + osl_getSystemTime( &aEndTime ); + + double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0); + double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0); + + printf( "System latency per call : %g\n" , (( fEnd-fStart )/2.) / ((double)(nLoop)) ); +} + +void main( int argc, char *argv[] ) +{ + sal_Bool bUseNew = ( 3 == argc ); +#ifdef SOLARIS + ChangeGlobalInit(); // Switch on threads ! +#endif + if( argc < 2 ) + { + printf( + "usage : testclient [-r] connectionstring\n" + " -r reverse call me test (server calls client)" + ); + return; + } + + OUString sConnectionString; + OUString sProtocol; + sal_Bool bLatency = sal_False; + sal_Bool bReverse = sal_False; + + parseCommandLine( argv , &sConnectionString , &sProtocol , &bLatency , &bReverse ); + + { + Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM("client.rdb")) ); + + + Reference < XConnector > rConnector( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector")), + OUString( RTL_CONSTASCII_USTRINGPARAM("connectr")), + rSMgr ), + UNO_QUERY ); + + + try + { + Reference < XConnection > rConnection = + rConnector->connect( sConnectionString ); + + printf( "%s\n" , OUStringToOString( rConnection->getDescription(), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + + if( bLatency ) + { + testLatency( rConnection , sal_False ); + testLatency( rConnection , sal_True ); + } + else + { + // just ensure that it is registered + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")), + OUString( RTL_CONSTASCII_USTRINGPARAM("iiopbrdg")), + rSMgr ); + + Reference < XBridgeFactory > rFactory( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")), + OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr")), + rSMgr ), + UNO_QUERY ); + + if( rFactory.is() ) + { + + Reference < XBridge > rBridge = rFactory->createBridge( + OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")), + sProtocol, + rConnection, + new OInstanceProvider ); + { + // test the factory + Reference < XBridge > rBridge2 = rFactory->getBridge( OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")) ); + assert( rBridge2.is() ); + assert( rBridge2->getDescription() == rBridge->getDescription( ) ); + assert( rBridge2->getName() == rBridge->getName() ); + assert( rBridge2 == rBridge ); + } + + + Reference < XInterface > rInitialObject = rBridge->getInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM("bridges-testobject")) ); + + if( rInitialObject.is() ) + { + printf( "got the remote object\n" ); + if( ! bReverse ) + { + // Reference < XComponent > rPerfTest( rInitialObject , UNO_QUERY ); +// if( rPerfTest.is() ) +// { +// // doPerformanceTest( rPerfTest ); +// } +// else +// { + testRemote( rInitialObject ); +// } + } + } +// Reference < XComponent > rComp( rBridge , UNO_QUERY ); +// rComp->dispose(); + + rInitialObject = Reference < XInterface > (); + printf( "Waiting...\n" ); + TimeValue value={bReverse ?1000 :2,0}; + osl_waitThread( &value ); + printf( "Closing...\n" ); + } + + Reference < XBridge > rBridge = rFactory->getBridge( OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")) ); +// assert( ! rBridge.is() ); + } + + } + catch( Exception &e ) + { + OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ); + printf( "Login failed, got an Exception !\n%s\n" , o.pData->buffer ); + } + + + Reference < XComponent > rComp( rSMgr , UNO_QUERY ); + rComp->dispose(); + } + printf( "Closed\n" ); +} + diff --git a/bridges/test/testclient.java b/bridges/test/testclient.java new file mode 100644 index 000000000000..2a8908bd3dde --- /dev/null +++ b/bridges/test/testclient.java @@ -0,0 +1,190 @@ +/************************************************************************* + * + * $RCSfile: testclient.java,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.IBridge; +import com.sun.star.connection.XConnector; +import com.sun.star.connection.XConnection; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.bridge.XInstanceProvider; + +import test.XCallMe; +import test.XTestFactory; + + +class MyInstanceProvider implements XInstanceProvider +{ + public Object getInstance( String sName ) + { + System.out.println( "getInstance called" ); + return new MyTestFactory(); + } + +} + + +class MyTestFactory implements XTestFactory +{ + public XCallMe createCallMe( ) throws com.sun.star.uno.RuntimeException + { + return new MyCallMe(); + } + + public test.XInterfaceTest createInterfaceTest( ) throws com.sun.star.uno.RuntimeException + { + return null; + } + +} +class MyCallMe implements XCallMe +{ + public String getsAttribute() throws com.sun.star.uno.RuntimeException + { + return ""; + } + public void setsAttribute( String _sattribute ) throws com.sun.star.uno.RuntimeException + { + } + + // Methods + public void call( /*IN*/String s, /*IN*/int nToDo ) throws test.TestBridgeException, com.sun.star.uno.RuntimeException + { + + } + public void callOneway( /*IN*/String s, /*IN*/int nToDo ) throws com.sun.star.uno.RuntimeException + { + System.out.println( "entering callOneway" ); +// this.wait( 5 ); + try { + Thread.currentThread().sleep( 4000 ); + } + catch ( java.lang.Exception e ) + { + System.out.println( e ); + } + System.out.println( "leaving callOneway" ); + } + public void callAgain( /*IN*/XCallMe callAgain, /*IN*/int nToCall ) throws com.sun.star.uno.RuntimeException + { + + } + public test.TestTypes transport( /*IN*/test.TestTypes types ) throws com.sun.star.uno.RuntimeException + { + return new test.TestTypes(); + } + +} + +public class testclient +{ + static void main( String[] args ) + { + try { + + com.sun.star.comp.servicemanager.ServiceManager smgr = + new com.sun.star.comp.servicemanager.ServiceManager(); + smgr.addFactories( new String[] { "com.sun.star.comp.connections.Connector" }); + + Object x = smgr.createInstance("com.sun.star.connection.Connector"); + if( x == null ) + { + System.out.println( "couldn't create connector\n" ); + return; + } + + + XConnector xConnector = + ( XConnector ) UnoRuntime.queryInterface( XConnector.class , x ); + + XConnection xConnection = xConnector.connect(args[0]); + + if( null != xConnection ) + { + System.out.println( "after connect" ); + String rootOid = "OfficeDaemon.Factory"; + com.sun.star.uno.IBridge bridge = (IBridge ) UnoRuntime.getBridgeByName( + "java", + null, + "remote", + null, + new Object[]{"iiop", xConnection, new MyInstanceProvider()}); + + System.out.println( "after building bridge" ); +// Object rInitialObject = m_bridge.mapInterfaceFrom(rootOid, XInterface.class); +// XTestFactory rFactory = (XTestFactory ) +// UnoRuntime.queryInterface(XTestFactory.class,rInitialObject ); + +// XCallMe callMerFactory-> + Thread.currentThread().sleep( 100000 ); + } + } + catch( com.sun.star.uno.Exception e) + { + System.out.println( "Exception thrown" ); + } + catch( java.lang.Exception e) + { + System.out.println( "java.lang.Exception thrown" ); + } + + System.out.println( "exiting" ); + } +} diff --git a/bridges/test/testcomp.cxx b/bridges/test/testcomp.cxx new file mode 100644 index 000000000000..f4d74cc12494 --- /dev/null +++ b/bridges/test/testcomp.cxx @@ -0,0 +1,875 @@ +/************************************************************************* + * + * $RCSfile: testcomp.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <assert.h> +#include <string.h> +#include <stdlib.h> + +#include <uno/threadpool.h> + +#include <osl/mutex.hxx> +#include <osl/diagnose.h> + +#include <test/XTestFactory.hpp> +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/bridge/XInstanceProvider.hpp> + +#include <com/sun/star/registry/XImplementationRegistration.hpp> + +#include <com/sun/star/test/performance/XPerformanceTest.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <cppuhelper/weak.hxx> + +using namespace ::test; +using namespace ::rtl; +using namespace ::test; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::test::performance; + +#include "testcomp.h" + + +void parseCommandLine( char *argv[] , + ::rtl::OUString *pConnection , ::rtl::OUString *pProtocol , + sal_Bool *pbLatency , sal_Bool *pbReverse) +{ + sal_Int32 nArgIndex = 1; + if( ! strcmp( argv[1] , "-r" ) ) + { + nArgIndex = 2; + *pbReverse = sal_True; + } + else if( ! strcmp( argv[1] , "-latency" ) ) + { + *pbLatency = sal_True; + nArgIndex = 2; + } + + OUString sTemp = OUString::createFromAscii( argv[nArgIndex] ); + sal_Int32 nIndex = sTemp.indexOf( ';' ); + if( -1 == nIndex ) + { + *pConnection = sTemp; + *pProtocol = OUString( RTL_CONSTASCII_USTRINGPARAM( "iiop" ) ); + } + else + { + *pConnection = sTemp.copy( 0 , nIndex ); + *pProtocol = sTemp.copy( nIndex+1, sTemp.getLength() - (nIndex+1) ); + } +} + +Any OInstanceProvider::queryInterface( const Type & aType ) +{ + Any a = ::cppu::queryInterface( aType , + SAL_STATIC_CAST( XInstanceProvider * , this ) ); + if( a.hasValue() ) + { + return a; + } + return OWeakObject::queryInterface( aType ); +} + +::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > + OInstanceProvider::getInstance( const ::rtl::OUString& sObjectName ) + throw(::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException) +{ + // Tries to get the PerformanceTestObject + if( sObjectName == OUString( RTL_CONSTASCII_USTRINGPARAM( "TestRemoteObject" ) ) ) + { + return m_rSMgr->createInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.test.performance.PerformanceTestObject") ) ); + } + return Reference < XInterface > ( (::cppu::OWeakObject * ) new OTestFactory() ); +} + +class ServiceImpl + : public XServiceInfo + , public XPerformanceTest +{ + OUString _aDummyString; + Any _aDummyAny; + Sequence< Reference< XInterface > > _aDummySequence; + ComplexTypes _aDummyStruct; + RuntimeException _aDummyRE; + + sal_Int32 _nRef; + +public: + ServiceImpl() + : _nRef( 0 ) + {} + ServiceImpl( const Reference< XMultiServiceFactory > & xMgr ) + : _nRef( 0 ) + {} + + // XInterface + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw(::com::sun::star::uno::RuntimeException) + { + // execution time remains appr. constant any time + Any aRet; + if (aType == ::getCppuType( (const Reference< XInterface > *)0 )) + { + void * p = (XInterface *)(XPerformanceTest *)this; + aRet.setValue( &p, ::getCppuType( (const Reference< XInterface > *)0 ) ); + } + if (aType == ::getCppuType( (const Reference< XPerformanceTest > *)0 )) + { + void * p = (XPerformanceTest *)this; + aRet.setValue( &p, ::getCppuType( (const Reference< XPerformanceTest > *)0 ) ); + } + if (! aRet.hasValue()) + { + void * p = (XPerformanceTest *)this; + Any aDummy( &p, ::getCppuType( (const Reference< XPerformanceTest > *)0 ) ); + } + return aRet; + } + virtual void SAL_CALL acquire() throw(::com::sun::star::uno::RuntimeException) + { osl_incrementInterlockedCount( &_nRef ); } + virtual void SAL_CALL release() throw(::com::sun::star::uno::RuntimeException) + { if (! osl_decrementInterlockedCount( &_nRef )) delete this; } + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw (RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException); + + // Attributes + virtual sal_Int32 SAL_CALL getLong_attr() throw(::com::sun::star::uno::RuntimeException) + { return 0; } + virtual void SAL_CALL setLong_attr( sal_Int32 _attributelong ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual sal_Int64 SAL_CALL getHyper_attr() throw(::com::sun::star::uno::RuntimeException) + { return 0; } + virtual void SAL_CALL setHyper_attr( sal_Int64 _attributehyper ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual float SAL_CALL getFloat_attr() throw(::com::sun::star::uno::RuntimeException) + { return 0.0; } + virtual void SAL_CALL setFloat_attr( float _attributefloat ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual double SAL_CALL getDouble_attr() throw(::com::sun::star::uno::RuntimeException) + { return 0.0; } + virtual void SAL_CALL setDouble_attr( double _attributedouble ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual OUString SAL_CALL getString_attr() throw(::com::sun::star::uno::RuntimeException) + { return _aDummyString; } + virtual void SAL_CALL setString_attr( const ::rtl::OUString& _attributestring ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual Reference< XInterface > SAL_CALL getInterface_attr() throw(::com::sun::star::uno::RuntimeException) + { return Reference< XInterface >(); } + virtual void SAL_CALL setInterface_attr( const Reference< XInterface >& _attributeinterface ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual Any SAL_CALL getAny_attr() throw(::com::sun::star::uno::RuntimeException) + { return _aDummyAny; } + virtual void SAL_CALL setAny_attr( const Any& _attributeany ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual Sequence< Reference< XInterface > > SAL_CALL getSequence_attr() throw(::com::sun::star::uno::RuntimeException) + { return _aDummySequence; } + virtual void SAL_CALL setSequence_attr( const Sequence< Reference< XInterface > >& _attributesequence ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual ComplexTypes SAL_CALL getStruct_attr() throw(::com::sun::star::uno::RuntimeException) + { return _aDummyStruct; } + virtual void SAL_CALL setStruct_attr( const ::com::sun::star::test::performance::ComplexTypes& _attributestruct ) throw(::com::sun::star::uno::RuntimeException) + {} + + // Methods + virtual sal_Int32 SAL_CALL getLong() throw(::com::sun::star::uno::RuntimeException) + { return 0; } + virtual void SAL_CALL setLong( sal_Int32 _long ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual sal_Int64 SAL_CALL getHyper() throw(::com::sun::star::uno::RuntimeException) + { return 0; } + virtual void SAL_CALL setHyper( sal_Int64 _hyper ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual float SAL_CALL getFloat() throw(::com::sun::star::uno::RuntimeException) + { return 0; } + virtual void SAL_CALL setFloat( float _float ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual double SAL_CALL getDouble() throw(::com::sun::star::uno::RuntimeException) + { return 0; } + virtual void SAL_CALL setDouble( double _double ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual OUString SAL_CALL getString() throw(::com::sun::star::uno::RuntimeException) + { return _aDummyString; } + virtual void SAL_CALL setString( const ::rtl::OUString& _string ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual Reference< XInterface > SAL_CALL getInterface() throw(::com::sun::star::uno::RuntimeException) + { return Reference< XInterface >(); } + virtual void SAL_CALL setInterface( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _interface ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual Any SAL_CALL getAny() throw(::com::sun::star::uno::RuntimeException) + { return _aDummyAny; } + virtual void SAL_CALL setAny( const ::com::sun::star::uno::Any& _any ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual Sequence< Reference< XInterface > > SAL_CALL getSequence() throw(::com::sun::star::uno::RuntimeException) + { return _aDummySequence; } + virtual void SAL_CALL setSequence( const Sequence< Reference< XInterface > >& _sequence ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual ComplexTypes SAL_CALL getStruct() throw(::com::sun::star::uno::RuntimeException) + { return _aDummyStruct; } + virtual void SAL_CALL setStruct( const ::com::sun::star::test::performance::ComplexTypes& c ) throw(::com::sun::star::uno::RuntimeException) + {} + + virtual void SAL_CALL async() throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL sync() throw(::com::sun::star::uno::RuntimeException) + {} + virtual ComplexTypes SAL_CALL complex_in( const ::com::sun::star::test::performance::ComplexTypes& aVal ) throw(::com::sun::star::uno::RuntimeException) + { return aVal; } + virtual ComplexTypes SAL_CALL complex_inout( ::com::sun::star::test::performance::ComplexTypes& aVal ) throw(::com::sun::star::uno::RuntimeException) + { return aVal; } + virtual void SAL_CALL complex_oneway( const ::com::sun::star::test::performance::ComplexTypes& aVal ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual void SAL_CALL complex_noreturn( const ::com::sun::star::test::performance::ComplexTypes& aVal ) throw(::com::sun::star::uno::RuntimeException) + {} + virtual Reference< XPerformanceTest > SAL_CALL createObject() throw(::com::sun::star::uno::RuntimeException) + { return new ServiceImpl(); } + virtual void SAL_CALL raiseRuntimeException( ) throw(::com::sun::star::uno::RuntimeException) + { throw _aDummyRE; } +}; + + +void ServiceImpl::async() throw(::com::sun::star::uno::RuntimeException) +{} + +// XServiceInfo +//__________________________________________________________________________________________________ +OUString ServiceImpl::getImplementationName() + throw (RuntimeException) +{ + return OUString( ); +} +//__________________________________________________________________________________________________ +sal_Bool ServiceImpl::supportsService( const OUString & rServiceName ) + throw (RuntimeException) +{ + return sal_False; +} +//__________________________________________________________________________________________________ +Sequence< OUString > ServiceImpl::getSupportedServiceNames() + throw (RuntimeException) +{ + return Sequence< OUString > (); +} + +/****************** + * OCallMe + * + *****************/ + +Any OCallMe::queryInterface( const Type & aType ) +{ + Any a = ::cppu::queryInterface( aType, + SAL_STATIC_CAST( XCallMe * , this ) ); + + if( a.hasValue() ) + { + return a; + } + + return OWeakObject::queryInterface( aType ); +} + +void OCallMe::call( const ::rtl::OUString& s, sal_Int32 nToDo ) + throw( RuntimeException, ::test::TestBridgeException) +{ + if( nToDo < 0 ) + { + throw TestBridgeException(); + } + + OUString sDummy; + if( ! nToDo ) { + OString o = OUStringToOString( s,RTL_TEXTENCODING_ASCII_US); + printf( "%s\n" , o.pData->buffer ); + } + for( sal_Int32 i = 0 ; i < nToDo ; i ++ ) + { + sDummy += s; + } +} + +void SAL_CALL OCallMe::drawLine( sal_Int32 x1, sal_Int32 y1 , sal_Int32 x2 , sal_Int32 y2 ) + throw(::com::sun::star::uno::RuntimeException) +{ + // do nothings +} + +void OCallMe::callOneway( const ::rtl::OUString& s, sal_Int32 nToDo ) + throw(RuntimeException) +{ + static int iBefore = 0; + + OUString sDummy; + m_nLastToDos = nToDo; + + + if( nToDo ) + { + printf( "+" ); + fflush( stdout ); + + TimeValue val = { nToDo , 0 }; + osl_waitThread( &val ); + printf( "-\n" ); + } + +} + +::test::TestTypes SAL_CALL OCallMe::transport( const ::test::TestTypes& types ) + throw(::com::sun::star::uno::RuntimeException) +{ + return types; +} + +::rtl::OUString OCallMe::getsAttribute() throw(RuntimeException) +{ + return m_sAttribute; +} +void OCallMe::setsAttribute( const ::rtl::OUString& _sattribute ) + throw(RuntimeException) +{ + m_sAttribute = _sattribute; +} +void OCallMe::callAgain( const Reference< ::test::XCallMe >& callAgain, + sal_Int32 nToCall ) throw(RuntimeException) +{ + ::osl::MutexGuard guard( m_mutex ); + if( nToCall %2 ) + { + printf( "Deadlocktest pong %d\n", nToCall ); + } + else + { + printf( "Deadlocktest ping %d\n", nToCall ); + } + if( nToCall ) + { + callAgain->callAgain( Reference< XCallMe > ( (XCallMe *) this ) , nToCall -1 ); + } +} + +/******************** + * OInterfaceTest + * + *******************/ +Any OInterfaceTest::queryInterface( const Type & aType ) +{ + Any a = ::cppu::queryInterface( aType, + SAL_STATIC_CAST( XInterfaceTest * , this ) ); + if( a.hasValue() ) + { + return a; + } + return OWeakObject::queryInterface( aType ); +} + + +void OInterfaceTest::setIn( + const Reference< ::test::XCallMe >& callback ) + throw(RuntimeException) +{ + m_rCallMe = callback; + call(); +} + +void OInterfaceTest::setInOut( Reference< ::test::XCallMe >& callback ) + throw(RuntimeException) +{ + Reference< XCallMe > r = m_rCallMe; + m_rCallMe = callback; + callback = r; + call(); +} + + +void OInterfaceTest::getOut( Reference< ::test::XCallMe >& callback ) + throw(RuntimeException) +{ + callback = m_rCallMe; +} + +Reference< ::test::XCallMe > OInterfaceTest::get( ) + throw(RuntimeException) +{ + call(); + return m_rCallMe; +} + +void OInterfaceTest::call() +{ + if( m_rCallMe.is() ) + { + m_rCallMe->call( OUString( RTL_CONSTASCII_USTRINGPARAM("This is my String during a callback!")) , 5); + } +} + + +Any OTestFactory::queryInterface( const Type & aType ) +{ + Any a = ::cppu::queryInterface( aType, + SAL_STATIC_CAST( XTestFactory * , this ) ); + + if( a.hasValue() ) + { + return a; + } + + return OWeakObject::queryInterface( aType ); +} + +Reference< ::test::XCallMe > OTestFactory::createCallMe( ) + throw(RuntimeException) +{ + return Reference< XCallMe > ( (XCallMe * ) new OCallMe() ); +} + +Reference< ::test::XInterfaceTest > SAL_CALL OTestFactory::createInterfaceTest( ) + throw(RuntimeException) +{ + return Reference < XInterfaceTest > ( (XInterfaceTest * ) new OInterfaceTest() ); +} + + + +/******************************************************** + * + ********************************************************/ +/*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, +// public XInstanceProvider +// { +// public: +// OInstanceProvider( ){} +// ~OInstanceProvider(){ printf( "instance provider 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 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL +// getInstance( const ::rtl::OUString& sObjectName ) +// throw( ::com::sun::star::container::NoSuchElementException, +// ::com::sun::star::uno::RuntimeException); +// }; + + + + + + + + +double getCallsPerSec( const Reference < XCallMe > &rCall , int nLoops, int nToDo ) +{ + TimeValue aStartTime, aEndTime; + osl_getSystemTime( &aStartTime ); + for( sal_Int32 i = 0; i < nLoops; i ++ ) + { + rCall->call( OUString( RTL_CONSTASCII_USTRINGPARAM("Performance test string")) , nToDo ); + } + osl_getSystemTime( &aEndTime ); + + double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0); + double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0); + return fEnd-fStart; +} + +double getCallsPerSecOneway( const Reference < XCallMe > &rCall , + int nLoops, + int nToDo, + double *pdAfterExecution + ) +{ + TimeValue aStartTime, aEndTime, aAfterExecution; + osl_getSystemTime( &aStartTime ); + for( sal_Int32 i = 0; i < nLoops; i ++ ) + { +// rCall->callOneway( OUString( RTL_CONSTASCII_USTRINGPARAM("Performance test string" )), 0 ); + rCall->drawLine( 0 , 0 , 500 , 123 ); + } + osl_getSystemTime( &aEndTime ); + + rCall->call( OUString( RTL_CONSTASCII_USTRINGPARAM("Performance test string")) , nToDo ); + osl_getSystemTime( &aAfterExecution ); + + double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0); + double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0); + *pdAfterExecution = (double)aAfterExecution.Seconds + + ((double)aAfterExecution.Nanosec / 1000000000.0) - fStart; + return fEnd-fStart; +} + +void testOnewayPerformanceOnTwoInterfaces( + const Reference < XCallMe > &rRemote1, const Reference < XCallMe > &rRemote2 ) +{ + printf( "Doing oneway performance test on two interfaces ...\n" ); + const sal_Int32 nLoops = 10000; + TimeValue aStartTime, aEndTime, aAfterExecution; + osl_getSystemTime( &aStartTime ); + for( sal_Int32 i = 0; i < nLoops ; i ++ ) + { + rRemote1->drawLine( 0 , 0 , 500 , 123 ); + rRemote2->drawLine( 0 , 0 , 500 , 123 ); + } + osl_getSystemTime( &aEndTime ); + double fStart = (double)aStartTime.Seconds + ((double)aStartTime.Nanosec / 1000000000.0); + double fEnd = (double)aEndTime.Seconds + ((double)aEndTime.Nanosec / 1000000000.0); + + printf( "Overhead per Call [ms] %g\n" , ((fEnd-fStart)/((double)nLoops/1000 ))/2. ); +} + +void testPerformance( const Reference < XCallMe > &rRemote, + const Reference < XCallMe > &rLocal ) +{ + OUString aTestString; + + sal_Int32 nDoSomething = 1; + sal_Int32 nCalls = 80000; + double dRemote, dLocal,dAfterExecution; + + printf( "performance test oneway...\n" ); + dLocal = getCallsPerSecOneway( rLocal , nCalls , nDoSomething , &dAfterExecution); + dRemote = getCallsPerSecOneway( rRemote , nCalls , nDoSomething , &dAfterExecution); + printf( "Local=%g s," + "Remote : %g s\n" , dLocal, dRemote ); + if( dLocal > 0. ) + { + printf( "Remote/Local : %g\n", dRemote/dLocal ); + } + + printf( "Overhead per Call [ms] %g\n" , (dRemote - dLocal)/((double)nCalls/1000 ) ); + printf( "Overhead per Call after completion [ms] %g\n" , (dAfterExecution - dLocal)/((double)nCalls/1000 ) ); + + nCalls = 2000; + + printf( "Doing performance test ...\n" ); + dRemote = getCallsPerSec( rRemote , nCalls , nDoSomething ); + dLocal = getCallsPerSec( rLocal , nCalls , nDoSomething ); + printf( "Local=%g s,\n" + "Remote=%g s\n" , dLocal, dRemote ); + if( dLocal > 0. ) + { + printf( "Remote/Local : %g\n", dRemote/dLocal ); + } + printf( "Overhead per synchron Call [ms] %g\n" , ((dRemote - dLocal)/((double)nCalls/1000 )) ); +} + +void testException( const Reference < XCallMe > &r ) +{ + try { + r->call( OUString( RTL_CONSTASCII_USTRINGPARAM("dummy")) , -1 ); + assert( ! "no exception flown !" ); + } + catch( TestBridgeException & e ) + { + // Exception flew successfully ! + } + catch( Exception & e ) + { + assert( ! "only base class of exception could be catched!" ); + } + catch(...) + { + assert(! "wrong unknown exception !" ); + } +} + +void testSequenceOfCalls( const Reference< XCallMe > & rRCallMe ) +{ + printf( "Testing sequence of calls\n" ); + for( sal_Int32 i = 0 ; i < 800 ; i ++ ) + { + rRCallMe->callOneway( OUString( RTL_CONSTASCII_USTRINGPARAM("hifuj" )), 0 ); + } +} + +void testAllTypes( const Reference < XCallMe > & rRCallMe ) +{ + printf( "Testing all types\n" ); + + for( sal_Int32 i = 0; i < 32 ; i ++ ) + { + + TestTypes types; + types.Bool = sal_True; + types.Char = L'i'; + types.Byte = -12; + types.Short = -32000; + types.UShort = (sal_uInt16 ) (1 << i); + types.Long = -123; + types.ULong = 1 << i; + types.Hyper = 50; + types.UHyper = 1 << i*2; + types.Float = (float)123.239; + types.Double = 1279.12490012; + types.String = OUString( RTL_CONSTASCII_USTRINGPARAM("abcdefghijklmnopqrstuvwxyz")); + types.Interface = Reference< XInterface >( rRCallMe , UNO_QUERY); + types.Any <<= types.Double; + + TestTypes retTypes = rRCallMe->transport( types ); + + OSL_ASSERT( ( types.Bool && retTypes.Bool ) || ( ! types.Bool && ! retTypes.Bool ) ); + OSL_ASSERT( types.Char == retTypes.Char ); + OSL_ASSERT( types.Byte == retTypes.Byte ); + OSL_ASSERT( types.Short == retTypes.Short ); + OSL_ASSERT( types.UShort == retTypes.UShort ); + OSL_ASSERT( types.Long == retTypes.Long ); + OSL_ASSERT( types.ULong == retTypes.ULong ); + OSL_ASSERT( types.Hyper == retTypes.Hyper ); + OSL_ASSERT( types.UHyper == retTypes.UHyper ); + OSL_ASSERT( types.Float == retTypes.Float ); + OSL_ASSERT( types.Double == retTypes.Double ); + OSL_ASSERT( types.String == retTypes.String ); + OSL_ASSERT( types.Interface == retTypes.Interface ); + OSL_ASSERT( types.Any == retTypes.Any ); + } + +} + +void testRemote( const Reference< XInterface > &rRemote ) +{ + char a; + getCppuType( (sal_Int8*)&a ); + + Reference< XTestFactory > rRFact( rRemote , UNO_QUERY ); + if( ! rRFact.is() ) + { + printf( "remote object doesn't support XTestFactory\n" ); + return; + } + OSL_ASSERT( rRFact.is() ); + Reference< XCallMe > rLCallMe = (XCallMe * ) new OCallMe(); + Reference< XCallMe > rRCallMe = rRFact->createCallMe(); + + testAllTypes( rLCallMe ); + testAllTypes( rRCallMe ); + + printf( "Testing exception local ...\n" ); + testException( rLCallMe ); + printf( "Testing exception remote ...\n" ); + testException( rRCallMe ); + + //-------------------- + // Test attributes + //---------------------- + OUString ow = OUString::createFromAscii( "dum didel dum dideldei" ); + rLCallMe->setsAttribute( ow ); + OSL_ASSERT( rLCallMe->getsAttribute() == ow ); + + rRCallMe->setsAttribute( ow ); + OSL_ASSERT( rRCallMe->getsAttribute() == ow ); + + //------------------- + // Performance test + //------------------- + testPerformance( rRCallMe , rLCallMe ); + testOnewayPerformanceOnTwoInterfaces( rRFact->createCallMe(), rRCallMe ); + + //---------------- + // Test sequence + //---------------- + testSequenceOfCalls( rRCallMe ); + + + // test triple to check if transporting the same interface multiple + // times causes any problems + Reference< XInterfaceTest > rRTest = rRFact->createInterfaceTest(); + Reference< XInterfaceTest > rRTest2 = rRFact->createInterfaceTest(); + Reference< XInterfaceTest > rRTest3 = rRFact->createInterfaceTest(); + + rRTest->setIn( rRCallMe ); + rRTest2->setIn( rRCallMe ); + rRTest3->setIn( rRCallMe ); + + OSL_ASSERT( rRTest->get() == rRCallMe ); + OSL_ASSERT( rRTest2->get() == rRCallMe ); + OSL_ASSERT( rRTest3->get() == rRCallMe ); + + rRTest->setIn( rLCallMe ); + rRTest2->setIn( rLCallMe ); + rRTest3->setIn( rLCallMe ); + + { + Reference< XCallMe > rLCallMe1 = (XCallMe * ) new OCallMe(); + Reference< XCallMe > rLCallMe2 = (XCallMe * ) new OCallMe(); + Reference< XCallMe > rLCallMe3 = (XCallMe * ) new OCallMe(); + rRTest->setIn( rLCallMe1 ); + rRTest2->setIn( rLCallMe2 ); + rRTest3->setIn( rLCallMe3 ); + OSL_ASSERT( rRTest->get() == rLCallMe1 ); + OSL_ASSERT( rRTest2->get() == rLCallMe2 ); + OSL_ASSERT( rRTest3->get() == rLCallMe3 ); + + rRTest->setIn( rLCallMe ); + rRTest2->setIn( rLCallMe ); + rRTest3->setIn( rLCallMe ); + + OSL_ASSERT( rRTest->get() == rLCallMe ); + OSL_ASSERT( rRTest2->get() == rLCallMe ); + OSL_ASSERT( rRTest3->get() == rLCallMe ); + } + + Reference < XCallMe > r = rRCallMe; + rRTest->setInOut( r ); + OSL_ASSERT( r == rLCallMe ); + OSL_ASSERT( ! ( r == rRCallMe ) ); + + // test empty references + rRTest->setIn( Reference < XCallMe > () ); + + //-------------------------------- + // test thread deadlocking + //-------------------------------- + rLCallMe->callAgain( rRCallMe, 20 ); + +} + + + + + + +Reference <XInterface > createComponent( const ::rtl::OUString &sService , + const ::rtl::OUString &sDllName, + const Reference < XMultiServiceFactory > &rSMgr ) +{ + Reference< XInterface > rInterface; + rInterface = rSMgr->createInstance( sService ); + + if( ! rInterface.is() ) + { + // erst registrieren + Reference < XImplementationRegistration > rReg ( + rSMgr->createInstance( + OUString::createFromAscii( "com.sun.star.registry.ImplementationRegistration" )), + UNO_QUERY ); + + OSL_ASSERT( rReg.is() ); +#ifdef SAL_W32 + OUString aDllName = sDllName; +#else + OUString aDllName = OUString( RTL_CONSTASCII_USTRINGPARAM("lib")); + aDllName += sDllName; + aDllName += OUString( RTL_CONSTASCII_USTRINGPARAM(".so")); +#endif + + try + { + rReg->registerImplementation( + OUString::createFromAscii( "com.sun.star.loader.SharedLibrary" ), + aDllName, + Reference< XSimpleRegistry > () ); + rInterface = rSMgr->createInstance( sService ); + } + catch( Exception & ) + { + printf( "couldn't register dll %s\n" , + OUStringToOString( aDllName, RTL_TEXTENCODING_ASCII_US ).getStr() ); + } + } + return rInterface; +} + + diff --git a/bridges/test/testcomp.h b/bridges/test/testcomp.h new file mode 100644 index 000000000000..19313afc63ea --- /dev/null +++ b/bridges/test/testcomp.h @@ -0,0 +1,214 @@ +/************************************************************************* + * + * $RCSfile: testcomp.h,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +//#include <com/sun/star/bridge/XServer.hpp> +//#include <com/sun/star/bridge/XClient.hpp> +#include <stdio.h> + +#include <com/sun/star/bridge/XInstanceProvider.hpp> +//#include <com/sun/star/bridge/XConnectionAdministration.hpp> +#include <vos/thread.hxx> +#include <vos/timer.hxx> + + +void parseCommandLine( char *argv[] , + ::rtl::OUString *pProtocol , ::rtl::OUString *pConnection , + sal_Bool *pbLatency , sal_Bool *pbReverse); + + +Reference< XInterface > createComponent( + const ::rtl::OUString &sServiceName, + const ::rtl::OUString &sDllName, + const Reference < XMultiServiceFactory > & rSMgr ); + +class OInterfaceTest : + public ::cppu::OWeakObject, + public XInterfaceTest +{ +public: + OInterfaceTest() {} + ~OInterfaceTest() {} + +public: + // XInterface + 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); + virtual void SAL_CALL setInOut( ::com::sun::star::uno::Reference< ::test::XCallMe >& callback ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL getOut( ::com::sun::star::uno::Reference< ::test::XCallMe >& callback ) throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::test::XCallMe > SAL_CALL get( ) throw(::com::sun::star::uno::RuntimeException); +private: + void call(); + +private: + Reference < XCallMe > m_rCallMe; +}; + + +class OCallMe : + public ::cppu::OWeakObject, + public XCallMe +{ +public: + OCallMe() : m_nLastToDos(-1) {} + ~OCallMe() {} + +public: + // XInterface + 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 ) + throw(::com::sun::star::uno::RuntimeException, + ::test::TestBridgeException); + virtual void SAL_CALL callOneway( const ::rtl::OUString& s, sal_Int32 nToDo ) + throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL drawLine( sal_Int32 x1, sal_Int32 y1 , sal_Int32 x2 , sal_Int32 y2 ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getsAttribute() throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setsAttribute( const ::rtl::OUString& _sattribute ) throw(::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL callAgain( const ::com::sun::star::uno::Reference< ::test::XCallMe >& callAgain, + sal_Int32 nToCall ) throw(::com::sun::star::uno::RuntimeException); + + virtual ::test::TestTypes SAL_CALL transport( const ::test::TestTypes& types ) + throw(::com::sun::star::uno::RuntimeException); + + ::osl::Mutex m_mutex; + ::rtl::OUString m_sAttribute; + sal_Int32 m_nLastToDos; +}; + +class OTestFactory : + public ::cppu::OWeakObject, + public XTestFactory +{ +public: + OTestFactory() {} + ~OTestFactory() {} + +public: + // XInterface + 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); + virtual ::com::sun::star::uno::Reference< ::test::XInterfaceTest > SAL_CALL createInterfaceTest( ) + throw(::com::sun::star::uno::RuntimeException); + +}; + +/* +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, + public XInstanceProvider +{ +public: + OInstanceProvider( ){} + OInstanceProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > & r ) : + m_rSMgr( r ) + {} + ~OInstanceProvider(){ printf( "instance provider 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 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL + getInstance( const ::rtl::OUString& sObjectName ) + throw( ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::uno::RuntimeException); + + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_rSMgr; +}; + +void testRemote( const Reference< XInterface > &rRemote ); diff --git a/bridges/test/testoffice.cxx b/bridges/test/testoffice.cxx new file mode 100644 index 000000000000..8b8d7a97c245 --- /dev/null +++ b/bridges/test/testoffice.cxx @@ -0,0 +1,314 @@ +/************************************************************************* + * + * $RCSfile: testoffice.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <assert.h> + +#include <osl/mutex.hxx> +#include <osl/thread.h> + +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/connection/XConnector.hpp> + +#include <com/sun/star/bridge/XBridgeFactory.hpp> + +#include <com/sun/star/uno/XNamingService.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/io/XOutputStream.hpp> + +#include <com/sun/star/text/XTextDocument.hpp> + +#include <com/sun/star/lang/XServiceInfo.hpp> + +#include <com/sun/star/lang/XComponent.hpp> + +#include <com/sun/star/frame/XComponentLoader.hpp> + +#include <cppuhelper/weak.hxx> + +#include <test/XTestFactory.hpp> + +using namespace ::test; +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::connection; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::text; + +#include "testcomp.h" + +#ifdef SAL_W32 +#include <conio.h> +#endif + +#ifdef SOLARIS +extern "C" void ChangeGlobalInit(); +#endif + +void mygetchar() +{ +#ifdef SAL_W32 + _getch(); +#else + getchar(); +#endif +} + + +void testPipe( const Reference < XMultiServiceFactory > & rSmgr ) +{ + Reference < XOutputStream > rOut( + rSmgr->createInstance( OUString::createFromAscii( "com.sun.star.io.Pipe" ) ), + UNO_QUERY ); + + assert( rOut.is() ); + + { + Sequence < sal_Int8 > seq( 10 ); + seq.getArray()[0] = 42; + rOut->writeBytes( seq ); + } + + + { + Sequence < sal_Int8 > seq; + Reference < XInputStream > rIn( rOut , UNO_QUERY ); + if( ! ( rIn->available() == 10) ) + printf( "wrong bytes available\n" ); + if( ! ( rIn->readBytes( seq , 10 ) == 10 ) ) + printf( "wrong bytes read\n" ); + if( ! ( 42 == seq.getArray()[0] ) ) + printf( "wrong element in sequence\n" ); + +// assert( 0 ); + } +} +#include<stdio.h> +#include<string.h> + +void testWriter( const Reference < XComponent > & rCmp ) +{ + + Reference< XTextDocument > rTextDoc( rCmp , UNO_QUERY ); + + Reference< XText > rText = rTextDoc->getText(); + Reference< XTextCursor > rCursor = rText->createTextCursor(); + Reference< XTextRange > rRange ( rCursor , UNO_QUERY ); + + char pcText[1024]; + pcText[0] = 0; + printf( "pleast type any text\n" ); + while( sal_True ) + { + scanf( "%s" , pcText ); + + if( !strcmp( pcText , "end" ) ) + { + break; + } + + strcat( pcText , " " ); + rText->insertString( rRange , OUString::createFromAscii( pcText ) , sal_False ); + } +} + +void testDocument( const Reference < XMultiServiceFactory > & rSmgr ) +{ + Reference < XComponentLoader > rLoader( + rSmgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.frame.Desktop" ))), + UNO_QUERY ); + + assert( rLoader.is() ); + + sal_Char *urls[] = { + "private:factory/swriter", + "private:factory/scalc", + "private:factory/sdraw", + "http://www.heise.de", + "file://h|/remote_interfaces.sdw" + }; + + sal_Char *docu[]= { + "a new writer document ...\n", + "a new calc document ...\n", + "a new draw document ...\n", + "www.heise.de\n", + "the remote_interfaces.sdw doc\n" + }; + + sal_Int32 i; + for( i = 0 ; i < 1 ; i ++ ) + { + printf( "press any key to open %s\n" , docu[i] ); + mygetchar(); + + Reference< XComponent > rComponent = + rLoader->loadComponentFromURL( + OUString::createFromAscii( urls[i] ) , + OUString( RTL_CONSTASCII_USTRINGPARAM("_blank")), + 0 , + Sequence < ::com::sun::star::beans::PropertyValue >() ); + + testWriter( rComponent ); + printf( "press any key to close the document\n" ); + mygetchar(); + rComponent->dispose(); + } + +} + +void doSomething( const Reference < XInterface > &r ) +{ + Reference < XNamingService > rName( r, UNO_QUERY ); + if( rName.is() ) + { + printf( "got the remote naming service !\n" ); + Reference < XInterface > rXsmgr = rName->getRegisteredObject( + OUString::createFromAscii( "StarOffice.ServiceManager" ) ); + + Reference < XMultiServiceFactory > rSmgr( rXsmgr , UNO_QUERY ); + if( rSmgr.is() ) + { + printf( "got the remote service manager !\n" ); + testPipe( rSmgr ); + testDocument( rSmgr ); + } + } +} + + +void main( int argc, char *argv[] ) +{ + +#ifdef SOLARIS + ChangeGlobalInit(); // Switch on threads ! +#endif + if( argc < 2 ) + { + printf( "usage : testclient host:port" ); + exit( 1 ); + } + + OUString sConnectionString; + OUString sProtocol; + sal_Bool bLatency = sal_False; + sal_Bool bReverse = sal_False; + parseCommandLine( argv , &sConnectionString , &sProtocol , &bLatency , &bReverse ); + { + Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM( "client.rdb" ) ) ); + + // just ensure that it is registered + + Reference < XConnector > rConnector( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector")), + OUString( RTL_CONSTASCII_USTRINGPARAM("connectr")), + rSMgr ), + UNO_QUERY ); + + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")), + OUString( RTL_CONSTASCII_USTRINGPARAM("iiopbrdg")), + rSMgr ); + + Reference < XBridgeFactory > rFactory( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")), + OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr")), + rSMgr ), + UNO_QUERY ); + + try + { + if( rFactory.is() && rConnector.is() ) + { + Reference < XConnection > rConnection = + rConnector->connect( sConnectionString ); + + Reference < XBridge > rBridge = rFactory->createBridge( + OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")), + sProtocol, + rConnection, + Reference < XInstanceProvider > () ); + + Reference < XInterface > rInitialObject + = rBridge->getInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("NamingService")) ); + + if( rInitialObject.is() ) + { + printf( "got the remote object\n" ); + doSomething( rInitialObject ); + } + TimeValue value={2,0}; + osl_waitThread( &value ); + } + } + catch (... ) { + printf( "Exception thrown\n" ); + } + + Reference < XComponent > rComp( rSMgr , UNO_QUERY ); + rComp->dispose(); + } + //_getch(); +} diff --git a/bridges/test/testsameprocess.cxx b/bridges/test/testsameprocess.cxx new file mode 100644 index 000000000000..137b4be4e530 --- /dev/null +++ b/bridges/test/testsameprocess.cxx @@ -0,0 +1,252 @@ +/************************************************************************* + * + * $RCSfile: testsameprocess.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <assert.h> + +#include <osl/mutex.hxx> +#include <osl/thread.h> + +#include <cppuhelper/servicefactory.hxx> + +#include <com/sun/star/bridge/XBridgeFactory.hpp> +#include <com/sun/star/connection/XAcceptor.hpp> +#include <com/sun/star/connection/XConnector.hpp> + +#include <com/sun/star/lang/XComponent.hpp> + +#include <cppuhelper/weak.hxx> + +#include <test/XTestFactory.hpp> + +#include <vos/thread.hxx> + +using namespace ::test; +using namespace ::rtl; +using namespace ::cppu; +using namespace ::vos; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::connection; +using namespace ::com::sun::star::registry; + +#ifdef SAL_W32 +#include <conio.h> +#endif + +#include "testcomp.h" +#include "osl/mutex.h" + +/********* + * + ********/ + +class MyThread : + public OThread +{ +public: + MyThread( const Reference< XAcceptor > &r , + const Reference< XBridgeFactory > &rFactory, + const OUString &sConnectionDescription) : + m_rAcceptor( r ), + m_rBridgeFactory ( rFactory ), + m_sConnectionDescription( sConnectionDescription ) + {} + virtual void SAL_CALL run(); + +private: + Reference < XAcceptor > m_rAcceptor; + Reference < XBridgeFactory > m_rBridgeFactory; + OUString m_sConnectionDescription; +}; + + + +void MyThread::run() +{ + + while ( sal_True ) + { + try + { + Reference < XConnection > rConnection = + m_rAcceptor->accept( m_sConnectionDescription ); + + if( ! rConnection.is() ) + { + break; + } + + Reference < XBridge > rBridge = + m_rBridgeFactory->createBridge( + OUString() , + OUString( RTL_CONSTASCII_USTRINGPARAM("iiop")) , + rConnection , + (XInstanceProvider * ) new OInstanceProvider ); + + + } + catch ( ... ) + { + printf( "Exception was thrown by acceptor thread\n" ); + break; + } + } +} + + +void main( int argc, char *argv[] ) +{ + if( argc < 2 ) + { + printf( "usage : testsamprocess host:port\n" ); + exit(1 ); + } + + { +#if SUPD>582 + Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM( "client.rdb" ) ) ); +#else + Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory( "client.rdb" ); +#endif + + + Reference < XConnector > rConnector( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Connector")), + OUString( RTL_CONSTASCII_USTRINGPARAM("connectr")), + rSMgr ), + UNO_QUERY ); + + Reference < XAcceptor > rAcceptor( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor")), + OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor")), + rSMgr ), + UNO_QUERY ); + + // just ensure that it is registered + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")), + OUString( RTL_CONSTASCII_USTRINGPARAM("iiopbrdg")), + rSMgr ); + + Reference < XBridgeFactory > rFactory( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")), + OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr")), + rSMgr ), + UNO_QUERY ); + + + MyThread threadAcceptor( rAcceptor , rFactory , OUString::createFromAscii( argv[1] ) ); + + threadAcceptor.create(); + TimeValue value={2,0}; + osl_waitThread( &value ); + + try + { + Reference < XConnection > rConnection = + rConnector->connect( OUString::createFromAscii( argv[1] ) ); + + printf( "%s\n" , OUStringToOString( rConnection->getDescription(), + RTL_TEXTENCODING_ASCII_US ).pData->buffer ); + + if( rFactory.is() ) + { + + Reference < XBridge > rBridge = rFactory->createBridge( + OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")), + OUString( RTL_CONSTASCII_USTRINGPARAM("iiop")), + rConnection, + Reference < XInstanceProvider > () ); + + Reference < XInterface > rInitialObject + = rBridge->getInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("bla")) ); + + if( rInitialObject.is() ) + { + printf( "got the remote object\n" ); + testRemote( rInitialObject ); + } + printf( "Closing...\n" ); + TimeValue value={2,0}; + osl_waitThread( &value ); + } + + Reference < XBridge > rBridge = rFactory->getBridge( + OUString( RTL_CONSTASCII_USTRINGPARAM("bla blub")) ); + assert( ! rBridge.is() ); + + } + catch( Exception & ) + { + printf( "Login failed, got an Exception !\n" ); + } + + rAcceptor->stopAccepting(); + threadAcceptor.join(); + + Reference < XComponent > rComp( rFactory , UNO_QUERY ); + rComp->dispose(); + + + rComp = Reference < XComponent > ( rSMgr , UNO_QUERY ); + rComp->dispose(); + } +} diff --git a/bridges/test/testserver.cxx b/bridges/test/testserver.cxx new file mode 100644 index 000000000000..48226762e9a5 --- /dev/null +++ b/bridges/test/testserver.cxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * $RCSfile: testserver.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: hr $ $Date: 2000-09-18 15:28:51 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#include <string.h> +#include <assert.h> + +#include <osl/mutex.hxx> +#include <osl/conditn.h> + +#include <vos/thread.hxx> +#include <vos/socket.hxx> + +#include <cppuhelper/servicefactory.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <com/sun/star/connection/XAcceptor.hpp> +#include <com/sun/star/connection/XConnection.hpp> + +#include <com/sun/star/bridge/XInstanceProvider.hpp> +#include <com/sun/star/bridge/XBridgeFactory.hpp> + +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XInitialization.hpp> + + +#include <test/XTestFactory.hpp> + +#include <cppuhelper/weak.hxx> + +using namespace ::test; +using namespace ::rtl; +using namespace ::vos; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::bridge; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::connection; +#include "testcomp.h" +#ifdef SAL_W32 +#include <conio.h> +#endif + +/********* + * + ********/ + + + +class MyThread : + public OThread +{ +public: + MyThread( const Reference< XAcceptor > &r , + const Reference< XBridgeFactory > &rFactory, + const Reference< XMultiServiceFactory > &rSMgr, + const OUString &sConnectionDescription, + const OUString &sProtocol, + sal_Bool bReverse, + sal_Bool bLatency ) : + m_rAcceptor( r ), + m_rBridgeFactory ( rFactory ), + m_sConnectionDescription( sConnectionDescription ), + m_sProtocol( sProtocol ), + m_bReverse( bReverse ), + m_bLatency( bLatency ), + m_rSMgr( rSMgr ) + {} + virtual void SAL_CALL run(); + + void latencyTest( const Reference< XConnection > &r ); + +private: + Reference < XAcceptor > m_rAcceptor; + Reference < XBridgeFactory > m_rBridgeFactory; + Reference < XMultiServiceFactory > m_rSMgr; + OUString m_sConnectionDescription; + OUString m_sProtocol; + sal_Bool m_bReverse; + sal_Bool m_bLatency; +}; + + +void MyThread::latencyTest( const Reference< XConnection > &r ) +{ + Sequence < sal_Int8 > s; + while( 12 == r->read( s , 12 ) ) + { + r->read( s , 188 ); + s = Sequence < sal_Int8 >(60); + r->write( s ); + } +} + +void MyThread::run() +{ + + while ( sal_True ) + { + try + { + Reference < XConnection > rConnection = + m_rAcceptor->accept( m_sConnectionDescription ); + + if( ! rConnection.is() ) + { + break; + } + if( m_bLatency ) + { + latencyTest( rConnection ); + } + else + { + + Reference < XBridge > rBridge = + m_rBridgeFactory->createBridge( + OUString() , + m_sProtocol, + rConnection , + (XInstanceProvider * ) new OInstanceProvider(m_rSMgr) ); + + + if( m_bReverse ) + { + printf( "doing reverse callme test (test is ok, when on each line a +- appears\n" ); + Reference < XInterface > r = rBridge->getInstance( + OUString( RTL_CONSTASCII_USTRINGPARAM("blubber" ))); + Reference < XTestFactory > rFactory( r , UNO_QUERY ); + Reference < XCallMe > rCallMe = rFactory->createCallMe(); + + for( sal_Int32 i = 0 ; i < 1 ; i ++ ) + { + rCallMe->callOneway( + OUString( RTL_CONSTASCII_USTRINGPARAM("my test string")) , 2 ); + } + printf( "all oneway are send\n" ); + rCallMe->call( OUString::createFromAscii( "reverse call me test finished" ) , 0 ); + printf( "revers callme test finished\n" ); + } + } + } + catch ( Exception & e ) + { + printf( "Exception was thrown by acceptor \n" ); + OString o = OUStringToOString( e.Message , RTL_TEXTENCODING_ASCII_US ); + printf( "%s\n" , o.getStr() ); + break; + } + catch ( ... ) + { + printf( "Exception was thrown by acceptor thread\n" ); + break; + } + } +} + + +#ifdef SOLARIS +extern "C" void ChangeGlobalInit(); +#endif + +void main( int argc, char *argv[] ) +{ +// testserver(); + + if( argc < 2 ) + { + printf( "usage : testserver [-r] connectionstring\n" + " -r does a reverse test (server calls client)\n" ); + exit(1 ); + } + + OUString sConnectionString; + OUString sProtocol; + sal_Bool bReverse = sal_False; + sal_Bool bLatency = sal_False; + + parseCommandLine( argv , &sConnectionString , &sProtocol , &bLatency , &bReverse ); + +#ifdef SOLARIS + ChangeGlobalInit(); // Switch on threads ! +#endif + + { + Reference< XMultiServiceFactory > rSMgr = createRegistryServiceFactory( + OUString( RTL_CONSTASCII_USTRINGPARAM( "server.rdb" ) ) ); + + Reference < XBridgeFactory > rBridgeFactory ( createComponent( + OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory")), + OUString( RTL_CONSTASCII_USTRINGPARAM("brdgfctr" )), + rSMgr ), + UNO_QUERY ); + + + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.Bridge.iiop")), + OUString( RTL_CONSTASCII_USTRINGPARAM("iiopbrdg")), + rSMgr ); + + + Reference < XAcceptor > rAcceptor( + createComponent( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor")), + OUString( RTL_CONSTASCII_USTRINGPARAM("acceptor")), + rSMgr ) , + UNO_QUERY ); + + MyThread thread( rAcceptor , + rBridgeFactory, + rSMgr, + sConnectionString, + sProtocol, + bReverse, + bLatency); + thread.create(); + +#ifdef SAL_W32 + _getch(); +#elif SOLARIS + getchar(); +#elif LINUX + TimeValue value={360,0}; + osl_waitThread( &value ); +#endif + printf( "Closing...\n" ); + + rAcceptor->stopAccepting(); + thread.join(); + + printf( "Closed\n" ); + + Reference < XComponent > rComp2( rBridgeFactory , UNO_QUERY ); + rComp2->dispose(); + Reference < XComponent > rComp( rSMgr, UNO_QUERY ); + rComp->dispose(); + } +} diff --git a/bridges/version.mk b/bridges/version.mk new file mode 100644 index 000000000000..a9c440164af3 --- /dev/null +++ b/bridges/version.mk @@ -0,0 +1,75 @@ +#************************************************************************* +# +# $RCSfile: version.mk,v $ +# +# $Revision: 1.1.1.1 $ +# +# last change: $Author: hr $ $Date: 2000-09-18 15:28:47 $ +# +# 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): _______________________________________ +# +# +# +#************************************************************************* + +# target +RMCXT_TARGET=rmcxt + +# the major +RMCXT_MAJOR=2 +# the minor +RMCXT_MINOR=0 +# the micro +RMCXT_MICRO=0 + +# this is a c++ compatible library +RMCXT_CPP=0 + |