diff options
Diffstat (limited to 'cppu/source/uno/lbenv.cxx')
-rw-r--r-- | cppu/source/uno/lbenv.cxx | 1195 |
1 files changed, 0 insertions, 1195 deletions
diff --git a/cppu/source/uno/lbenv.cxx b/cppu/source/uno/lbenv.cxx deleted file mode 100644 index 0cbc96214..000000000 --- a/cppu/source/uno/lbenv.cxx +++ /dev/null @@ -1,1195 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org 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 version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_cppu.hxx" - -#include "cppu/EnvDcp.hxx" - -#include "sal/alloca.h" -#include "osl/diagnose.h" -#include "osl/interlck.h" -#include "osl/mutex.hxx" -#include "osl/module.h" -#include "osl/process.h" -#include "rtl/process.h" -#include "rtl/unload.h" -#include "rtl/string.hxx" -#include "rtl/ustring.hxx" -#include "rtl/ustrbuf.hxx" -#include "rtl/instance.hxx" -#include "typelib/typedescription.h" -#include "uno/dispatcher.h" -#include "uno/environment.h" -#include "uno/lbnames.h" -#include "prim.hxx" -#include "destr.hxx" -#include "loadmodule.hxx" - -#include <boost/unordered_map.hpp> -#include <vector> -#include <stdio.h> - - -using ::rtl::OUString; - -namespace -{ - -//------------------------------------------------------------------------------ -inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1, - typelib_InterfaceTypeDescription * pTD2 ) -{ - return (pTD1 == pTD2 || - (((typelib_TypeDescription *)pTD1)->pTypeName->length == - ((typelib_TypeDescription *)pTD2)->pTypeName->length && - ::rtl_ustr_compare( - ((typelib_TypeDescription *) pTD1)->pTypeName->buffer, - ((typelib_TypeDescription *) pTD2)->pTypeName->buffer ) == 0)); -} - -struct ObjectEntry; -struct uno_DefaultEnvironment; - -//------------------------------------------------------------------------------ -struct InterfaceEntry -{ - sal_Int32 refCount; - void * pInterface; - uno_freeProxyFunc fpFreeProxy; - typelib_InterfaceTypeDescription * pTypeDescr; -}; - -struct ObjectEntry -{ - OUString oid; - sal_Int32 nRef; - ::std::vector< InterfaceEntry > aInterfaces; - bool mixedObject; - - inline ObjectEntry( const OUString & rOId_ ); - - inline void append( - uno_DefaultEnvironment * pEnv, - void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr, - uno_freeProxyFunc fpFreeProxy ); - inline InterfaceEntry * find( - typelib_InterfaceTypeDescription * pTypeDescr ); - inline sal_Int32 find( void * iface_ptr, ::std::size_t pos ); -}; - -//------------------------------------------------------------------------------ -struct FctPtrHash : - public ::std::unary_function< const void *, ::std::size_t > -{ - ::std::size_t operator () ( const void * pKey ) const - { return (::std::size_t) pKey; } -}; - -//------------------------------------------------------------------------------ -struct FctOUStringHash : - public ::std::unary_function< const OUString &, ::std::size_t > -{ - ::std::size_t operator () ( const OUString & rKey ) const - { return rKey.hashCode(); } -}; - -// mapping from environment name to environment -typedef ::boost::unordered_map< - OUString, uno_Environment *, FctOUStringHash, - ::std::equal_to< OUString > > OUString2EnvironmentMap; - -// mapping from ptr to object entry -typedef ::boost::unordered_map< - void *, ObjectEntry *, FctPtrHash, - ::std::equal_to< void * > > Ptr2ObjectMap; -// mapping from oid to object entry -typedef ::boost::unordered_map< - OUString, ObjectEntry *, FctOUStringHash, - ::std::equal_to< OUString > > OId2ObjectMap; - - -//============================================================================== -struct EnvironmentsData -{ - ::osl::Mutex mutex; - OUString2EnvironmentMap aName2EnvMap; - - EnvironmentsData() : isDisposing(false) {} - ~EnvironmentsData(); - - inline void getEnvironment( - uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext ); - inline void registerEnvironment( uno_Environment ** ppEnv ); - inline void getRegisteredEnvironments( - uno_Environment *** pppEnvs, sal_Int32 * pnLen, - uno_memAlloc memAlloc, const OUString & rEnvDcp ); - - bool isDisposing; -}; - -namespace -{ - struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {}; -} - -//============================================================================== -struct uno_DefaultEnvironment : public uno_ExtEnvironment -{ - sal_Int32 nRef; - sal_Int32 nWeakRef; - - ::osl::Mutex mutex; - Ptr2ObjectMap aPtr2ObjectMap; - OId2ObjectMap aOId2ObjectMap; - - uno_DefaultEnvironment( - const OUString & rEnvDcp_, void * pContext_ ); - ~uno_DefaultEnvironment(); -}; - -//______________________________________________________________________________ -inline ObjectEntry::ObjectEntry( OUString const & rOId_ ) - : oid( rOId_ ), - nRef( 0 ), - mixedObject( false ) -{ - aInterfaces.reserve( 2 ); -} - -//______________________________________________________________________________ -inline void ObjectEntry::append( - uno_DefaultEnvironment * pEnv, - void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr, - uno_freeProxyFunc fpFreeProxy ) -{ - InterfaceEntry aNewEntry; - if (! fpFreeProxy) - (*pEnv->acquireInterface)( pEnv, pInterface ); - aNewEntry.refCount = 1; - aNewEntry.pInterface = pInterface; - aNewEntry.fpFreeProxy = fpFreeProxy; - typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr ); - aNewEntry.pTypeDescr = pTypeDescr; - - ::std::pair< Ptr2ObjectMap::iterator, bool > insertion( - pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type( - pInterface, this ) ) ); - OSL_ASSERT( insertion.second || - (find( pInterface, 0 ) >= 0 && - // points to the same object entry: - insertion.first->second == this) ); - aInterfaces.push_back( aNewEntry ); -} - -//______________________________________________________________________________ -inline InterfaceEntry * ObjectEntry::find( - typelib_InterfaceTypeDescription * pTypeDescr_ ) -{ - OSL_ASSERT( ! aInterfaces.empty() ); - if (aInterfaces.empty()) - return 0; - - // shortcut common case: - OUString const & type_name = - OUString::unacquired( - &((typelib_TypeDescription *) pTypeDescr_)->pTypeName ); - if (type_name.equalsAsciiL( - RTL_CONSTASCII_STRINGPARAM("com.sun.star.uno.XInterface") )) - { - return &aInterfaces[ 0 ]; - } - - ::std::size_t nSize = aInterfaces.size(); - for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos ) - { - typelib_InterfaceTypeDescription * pITD = - aInterfaces[ nPos ].pTypeDescr; - while (pITD) - { - if (td_equals( pITD, pTypeDescr_ )) - return &aInterfaces[ nPos ]; - pITD = pITD->pBaseTypeDescription; - } - } - return 0; -} - -//______________________________________________________________________________ -inline sal_Int32 ObjectEntry::find( - void * iface_ptr, ::std::size_t pos ) -{ - ::std::size_t size = aInterfaces.size(); - for ( ; pos < size; ++pos ) - { - if (aInterfaces[ pos ].pInterface == iface_ptr) - return pos; - } - return -1; -} - -extern "C" -{ - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_registerInterface( - uno_ExtEnvironment * pEnv, void ** ppInterface, - rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) -{ - OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" ); - OUString const & rOId = OUString::unacquired( &pOId ); - - uno_DefaultEnvironment * that = - static_cast< uno_DefaultEnvironment * >( pEnv ); - ::osl::ClearableMutexGuard guard( that->mutex ); - - // try to insert dummy 0: - std::pair<OId2ObjectMap::iterator, bool> const insertion( - that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) ); - if (insertion.second) - { - ObjectEntry * pOEntry = new ObjectEntry( rOId ); - insertion.first->second = pOEntry; - ++pOEntry->nRef; // another register call on object - pOEntry->append( that, *ppInterface, pTypeDescr, 0 ); - } - else // object entry exists - { - ObjectEntry * pOEntry = insertion.first->second; - ++pOEntry->nRef; // another register call on object - InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr ); - - if (pIEntry) // type entry exists - { - ++pIEntry->refCount; - if (pIEntry->pInterface != *ppInterface) - { - void * pInterface = pIEntry->pInterface; - (*pEnv->acquireInterface)( pEnv, pInterface ); - guard.clear(); - (*pEnv->releaseInterface)( pEnv, *ppInterface ); - *ppInterface = pInterface; - } - } - else - { - pOEntry->append( that, *ppInterface, pTypeDescr, 0 ); - } - } -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_registerProxyInterface( - uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy, - rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) -{ - OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy, - "### null ptr!" ); - OUString const & rOId = OUString::unacquired( &pOId ); - - uno_DefaultEnvironment * that = - static_cast< uno_DefaultEnvironment * >( pEnv ); - ::osl::ClearableMutexGuard guard( that->mutex ); - - // try to insert dummy 0: - std::pair<OId2ObjectMap::iterator, bool> const insertion( - that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) ); - if (insertion.second) - { - ObjectEntry * pOEntry = new ObjectEntry( rOId ); - insertion.first->second = pOEntry; - ++pOEntry->nRef; // another register call on object - pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy ); - } - else // object entry exists - { - ObjectEntry * pOEntry = insertion.first->second; - - // first registration was an original, then registerProxyInterface(): - pOEntry->mixedObject |= - (!pOEntry->aInterfaces.empty() && - pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0); - - ++pOEntry->nRef; // another register call on object - InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr ); - - if (pIEntry) // type entry exists - { - if (pIEntry->pInterface == *ppInterface) - { - ++pIEntry->refCount; - } - else - { - void * pInterface = pIEntry->pInterface; - (*pEnv->acquireInterface)( pEnv, pInterface ); - --pOEntry->nRef; // manual revoke of proxy to be freed - guard.clear(); - (*freeProxy)( pEnv, *ppInterface ); - *ppInterface = pInterface; - } - } - else - { - pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy ); - } - } -} - -//------------------------------------------------------------------------------ -static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam) -{ - uno_ExtEnvironment * pEnv = va_arg(*pParam, uno_ExtEnvironment *); - void * pInterface = va_arg(*pParam, void *); - - OSL_ENSURE( pEnv && pInterface, "### null ptr!" ); - uno_DefaultEnvironment * that = - static_cast< uno_DefaultEnvironment * >( pEnv ); - ::osl::ClearableMutexGuard guard( that->mutex ); - - Ptr2ObjectMap::const_iterator const iFind( - that->aPtr2ObjectMap.find( pInterface ) ); - OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() ); - ObjectEntry * pOEntry = iFind->second; - if (! --pOEntry->nRef) - { - // cleanup maps - that->aOId2ObjectMap.erase( pOEntry->oid ); - sal_Int32 nPos; - for ( nPos = pOEntry->aInterfaces.size(); nPos--; ) - { - that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface ); - } - - // the last proxy interface of the environment might kill this - // environment, because of releasing its language binding!!! - guard.clear(); - - // release interfaces - for ( nPos = pOEntry->aInterfaces.size(); nPos--; ) - { - InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos]; - typelib_typedescription_release( - (typelib_TypeDescription *) rEntry.pTypeDescr ); - if (rEntry.fpFreeProxy) // is proxy or used interface? - { - (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface ); - } - else - { - (*pEnv->releaseInterface)( pEnv, rEntry.pInterface ); - } - } - - delete pOEntry; - } - else if (pOEntry->mixedObject) - { - OSL_ASSERT( !pOEntry->aInterfaces.empty() && - pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0 ); - - sal_Int32 index = pOEntry->find( pInterface, 1 ); - OSL_ASSERT( index > 0 ); - if (index > 0) - { - InterfaceEntry & entry = pOEntry->aInterfaces[ index ]; - OSL_ASSERT( entry.pInterface == pInterface ); - if (entry.fpFreeProxy != 0) - { - --entry.refCount; - if (entry.refCount == 0) - { - uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy; - typelib_TypeDescription * pTypeDescr = - reinterpret_cast< typelib_TypeDescription * >( - entry.pTypeDescr ); - - pOEntry->aInterfaces.erase( - pOEntry->aInterfaces.begin() + index ); - if (pOEntry->find( pInterface, index ) < 0) - { - // proxy ptr not registered for another interface: - // remove from ptr map -#if OSL_DEBUG_LEVEL > 0 - ::std::size_t erased = -#endif - that->aPtr2ObjectMap.erase( pInterface ); - OSL_ASSERT( erased == 1 ); - } - - guard.clear(); - - typelib_typedescription_release( pTypeDescr ); - (*fpFreeProxy)( pEnv, pInterface ); - } - } - } - } -} - -static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface) -{ - uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface); -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_getObjectIdentifier( - uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) -{ - OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" ); - if (*ppOId) - { - ::rtl_uString_release( *ppOId ); - *ppOId = 0; - } - - uno_DefaultEnvironment * that = - static_cast< uno_DefaultEnvironment * >( pEnv ); - ::osl::ClearableMutexGuard guard( that->mutex ); - - Ptr2ObjectMap::const_iterator const iFind( - that->aPtr2ObjectMap.find( pInterface ) ); - if (iFind == that->aPtr2ObjectMap.end()) - { - guard.clear(); - (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface ); - } - else - { - rtl_uString * hstr = iFind->second->oid.pData; - rtl_uString_acquire( hstr ); - *ppOId = hstr; - } -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_getRegisteredInterface( - uno_ExtEnvironment * pEnv, void ** ppInterface, - rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr ) -{ - OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" ); - if (*ppInterface) - { - (*pEnv->releaseInterface)( pEnv, *ppInterface ); - *ppInterface = 0; - } - - OUString const & rOId = OUString::unacquired( &pOId ); - uno_DefaultEnvironment * that = - static_cast< uno_DefaultEnvironment * >( pEnv ); - ::osl::MutexGuard guard( that->mutex ); - - OId2ObjectMap::const_iterator const iFind - ( that->aOId2ObjectMap.find( rOId ) ); - if (iFind != that->aOId2ObjectMap.end()) - { - InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr ); - if (pIEntry) - { - (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface ); - *ppInterface = pIEntry->pInterface; - } - } -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_getRegisteredInterfaces( - uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen, - uno_memAlloc memAlloc ) -{ - OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" ); - uno_DefaultEnvironment * that = - static_cast< uno_DefaultEnvironment * >( pEnv ); - ::osl::MutexGuard guard( that->mutex ); - - sal_Int32 nLen = that->aPtr2ObjectMap.size(); - sal_Int32 nPos = 0; - void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) ); - - Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() ); - Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() ); - while (iPos != iEnd) - { - (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first ); - ++iPos; - } - - *pppInterfaces = ppInterfaces; - *pnLen = nLen; -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_acquire( uno_Environment * pEnv ) -{ - uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; - ::osl_incrementInterlockedCount( &that->nWeakRef ); - ::osl_incrementInterlockedCount( &that->nRef ); -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_release( uno_Environment * pEnv ) -{ - uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; - if (! ::osl_decrementInterlockedCount( &that->nRef )) - { - // invoke dispose callback - if (pEnv->environmentDisposing) - { - (*pEnv->environmentDisposing)( pEnv ); - } - - OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" ); - } - // free memory if no weak refs left - if (! ::osl_decrementInterlockedCount( &that->nWeakRef )) - { - delete that; - } -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv ) -{ - uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; - ::osl_incrementInterlockedCount( &that->nWeakRef ); -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv ) -{ - uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; - if (! ::osl_decrementInterlockedCount( &that->nWeakRef )) - { - delete that; - } -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_harden( - uno_Environment ** ppHardEnv, uno_Environment * pEnv ) -{ - if (*ppHardEnv) - { - (*(*ppHardEnv)->release)( *ppHardEnv ); - *ppHardEnv = 0; - } - - EnvironmentsData & rData = theEnvironmentsData::get(); - - if (rData.isDisposing) - return; - - uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; - { - ::osl::MutexGuard guard( rData.mutex ); - if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead - { - that->nRef = 0; - return; - } - } - ::osl_incrementInterlockedCount( &that->nWeakRef ); - *ppHardEnv = pEnv; -} - -//------------------------------------------------------------------------------ -static void SAL_CALL defenv_dispose( uno_Environment * ) -{ -} -} - -//______________________________________________________________________________ -uno_DefaultEnvironment::uno_DefaultEnvironment( - const OUString & rEnvDcp_, void * pContext_ ) - : nRef( 0 ), - nWeakRef( 0 ) -{ - uno_Environment * that = reinterpret_cast< uno_Environment * >(this); - that->pReserved = 0; - // functions - that->acquire = defenv_acquire; - that->release = defenv_release; - that->acquireWeak = defenv_acquireWeak; - that->releaseWeak = defenv_releaseWeak; - that->harden = defenv_harden; - that->dispose = defenv_dispose; - that->pExtEnv = this; - // identifier - ::rtl_uString_acquire( rEnvDcp_.pData ); - that->pTypeName = rEnvDcp_.pData; - that->pContext = pContext_; - - // will be late initialized - that->environmentDisposing = 0; - - uno_ExtEnvironment::registerInterface = defenv_registerInterface; - uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface; - uno_ExtEnvironment::revokeInterface = defenv_revokeInterface; - uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier; - uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface; - uno_ExtEnvironment::getRegisteredInterfaces = - defenv_getRegisteredInterfaces; - -} - -//______________________________________________________________________________ -uno_DefaultEnvironment::~uno_DefaultEnvironment() -{ - ::rtl_uString_release( ((uno_Environment *) this)->pTypeName ); -} - -//============================================================================== -static void writeLine( - void * stream, const sal_Char * pLine, const sal_Char * pFilter ) -{ - if (pFilter && *pFilter) - { - // lookup pFilter in pLine - while (*pLine) - { - if (*pLine == *pFilter) - { - sal_Int32 nPos = 1; - while (pLine[nPos] && pFilter[nPos] == pLine[nPos]) - { - ++nPos; - } - if (! pFilter[nPos]) - { - if (stream) - { - fprintf( (FILE *) stream, "%s\n", pLine ); - } - else - { - OSL_TRACE( "%s\n", pLine ); - } - } - } - ++pLine; - } - } - else - { - if (stream) - { - fprintf( (FILE *) stream, "%s\n", pLine ); - } - else - { - fprintf( stderr, "%s\n", pLine ); - } - } -} - -//============================================================================== -static void writeLine( - void * stream, const OUString & rLine, const sal_Char * pFilter ) -{ - ::rtl::OString aLine( ::rtl::OUStringToOString( - rLine, RTL_TEXTENCODING_ASCII_US ) ); - writeLine( stream, aLine.getStr(), pFilter ); -} - -//############################################################################## -extern "C" void SAL_CALL uno_dumpEnvironment( - void * stream, uno_Environment * pEnv, const sal_Char * pFilter ) - SAL_THROW_EXTERN_C() -{ - OSL_ENSURE( pEnv, "### null ptr!" ); - ::rtl::OUStringBuffer buf; - - if (! pEnv->pExtEnv) - { - writeLine( stream, "###################################" - "###########################################", pFilter ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment: ") ); - buf.append( pEnv->pTypeName ); - writeLine( stream, buf.makeStringAndClear(), pFilter ); - writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter ); - return; - } - - writeLine( stream, "########################################" - "######################################", pFilter ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment dump: ") ); - buf.append( pEnv->pTypeName ); - writeLine( stream, buf.makeStringAndClear(), pFilter ); - - uno_DefaultEnvironment * that = - reinterpret_cast< uno_DefaultEnvironment * >(pEnv); - ::osl::MutexGuard guard( that->mutex ); - - Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap ); - OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() ); - while (iPos != that->aOId2ObjectMap.end()) - { - ObjectEntry * pOEntry = iPos->second; - - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ") ); - if (pOEntry->mixedObject) - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ") ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=") ); - buf.append( pOEntry->nRef, 10 ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"") ); - buf.append( pOEntry->oid ); - buf.append( (sal_Unicode) '\"' ); - writeLine( stream, buf.makeStringAndClear(), pFilter ); - - for ( ::std::size_t nPos = 0; - nPos < pOEntry->aInterfaces.size(); ++nPos ) - { - const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos]; - - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" - ") ); - buf.append( - ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName ); - if (rIEntry.fpFreeProxy) - { - buf.appendAscii( - RTL_CONSTASCII_STRINGPARAM("; proxy free=0x") ); - buf.append( - reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 ); - } - else - { - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original") ); - } - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x") ); - buf.append( - reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 ); - - if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0) - { - ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface ); - if (erased != 1) - { - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( - " (ptr not found in map!)") ); - } - } - writeLine( stream, buf.makeStringAndClear(), pFilter ); - } - ++iPos; - } - if (! ptr2obj.empty()) - writeLine( stream, "ptr map inconsistency!!!", pFilter ); - writeLine( stream, "#####################################" - "#########################################", pFilter ); -} - -//############################################################################## -extern "C" void SAL_CALL uno_dumpEnvironmentByName( - void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter ) - SAL_THROW_EXTERN_C() -{ - uno_Environment * pEnv = 0; - uno_getEnvironment( &pEnv, pEnvDcp, 0 ); - if (pEnv) - { - ::uno_dumpEnvironment( stream, pEnv, pFilter ); - (*pEnv->release)( pEnv ); - } - else - { - ::rtl::OUStringBuffer buf( 32 ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"") ); - buf.append( pEnvDcp ); - buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!") ); - writeLine( stream, buf.makeStringAndClear(), pFilter ); - } -} - -namespace -{ - class makeOIdPart - { - private: - OUString m_sOidPart; - public: - makeOIdPart() - { - ::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 ); - - m_sOidPart = aRet.makeStringAndClear(); - } - const OUString& getOIdPart() const { return m_sOidPart; } - }; - - class theStaticOIdPart : public rtl::Static<makeOIdPart, theStaticOIdPart> {}; -} - -//------------------------------------------------------------------------------ -inline static const OUString & unoenv_getStaticOIdPart() -{ - return theStaticOIdPart::get().getOIdPart(); -} - -extern "C" -{ - -//------------------------------------------------------------------------------ -static void SAL_CALL unoenv_computeObjectIdentifier( - uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface ) -{ - OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" ); - if (*ppOId) - { - ::rtl_uString_release( *ppOId ); - *ppOId = 0; - } - - uno_Interface * pUnoI = (uno_Interface *) - ::cppu::binuno_queryInterface( - pInterface, *typelib_static_type_getByTypeClass( - typelib_TypeClass_INTERFACE ) ); - if (0 != pUnoI) - { - (*pUnoI->release)( pUnoI ); - // interface - ::rtl::OUStringBuffer oid( 64 ); - oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 ); - oid.append( static_cast< sal_Unicode >(';') ); - // environment[context] - oid.append( ((uno_Environment *) pEnv)->pTypeName ); - oid.append( static_cast< sal_Unicode >('[') ); - oid.append( reinterpret_cast< sal_Int64 >( - reinterpret_cast< - uno_Environment * >(pEnv)->pContext ), 16 ); - // process;good guid - oid.append( unoenv_getStaticOIdPart() ); - OUString aStr( oid.makeStringAndClear() ); - ::rtl_uString_acquire( *ppOId = aStr.pData ); - } -} - -//============================================================================== -static void SAL_CALL unoenv_acquireInterface( - uno_ExtEnvironment *, void * pUnoI_ ) -{ - uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_); - (*pUnoI->acquire)( pUnoI ); -} - -//============================================================================== -static void SAL_CALL unoenv_releaseInterface( - uno_ExtEnvironment *, void * pUnoI_ ) -{ - uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_); - (*pUnoI->release)( pUnoI ); -} -} - -//______________________________________________________________________________ -EnvironmentsData::~EnvironmentsData() -{ - ::osl::MutexGuard guard( mutex ); - isDisposing = true; - - for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() ); - iPos != aName2EnvMap.end(); ++iPos ) - { - uno_Environment * pWeak = iPos->second; - uno_Environment * pHard = 0; - (*pWeak->harden)( &pHard, pWeak ); - (*pWeak->releaseWeak)( pWeak ); - - if (pHard) - { -#if OSL_DEBUG_LEVEL > 1 - ::uno_dumpEnvironment( 0, pHard, 0 ); -#endif - (*pHard->dispose)( pHard ); // send explicit dispose - (*pHard->release)( pHard ); - } - } -} - -//______________________________________________________________________________ -inline void EnvironmentsData::getEnvironment( - uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext ) -{ - if (*ppEnv) - { - (*(*ppEnv)->release)( *ppEnv ); - *ppEnv = 0; - } - - OUString aKey( - OUString::valueOf( reinterpret_cast< sal_IntPtr >(pContext) ) ); - aKey += rEnvDcp; - - // try to find registered mapping - OUString2EnvironmentMap::const_iterator const iFind( - aName2EnvMap.find( aKey ) ); - if (iFind != aName2EnvMap.end()) - { - uno_Environment * pWeak = iFind->second; - (*pWeak->harden)( ppEnv, pWeak ); - } -} - -//______________________________________________________________________________ -inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv ) -{ - OSL_ENSURE( ppEnv, "### null ptr!" ); - uno_Environment * pEnv = *ppEnv; - - OUString aKey( - OUString::valueOf( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) ); - aKey += pEnv->pTypeName; - - // try to find registered environment - OUString2EnvironmentMap::const_iterator const iFind( - aName2EnvMap.find( aKey ) ); - if (iFind == aName2EnvMap.end()) - { - (*pEnv->acquireWeak)( pEnv ); - ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion( - aName2EnvMap.insert( - OUString2EnvironmentMap::value_type( aKey, pEnv ) ) ); - OSL_ENSURE( - insertion.second, "### insertion of env into map failed?!" ); - } - else - { - uno_Environment * pHard = 0; - uno_Environment * pWeak = iFind->second; - (*pWeak->harden)( &pHard, pWeak ); - if (pHard) - { - if (pEnv) - (*pEnv->release)( pEnv ); - *ppEnv = pHard; - } - else // registered one is dead - { - (*pWeak->releaseWeak)( pWeak ); - (*pEnv->acquireWeak)( pEnv ); - aName2EnvMap[ aKey ] = pEnv; - } - } -} - -//______________________________________________________________________________ -inline void EnvironmentsData::getRegisteredEnvironments( - uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc, - const OUString & rEnvDcp ) -{ - OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" ); - - // max size - uno_Environment ** ppFound = (uno_Environment **)alloca( - sizeof(uno_Environment *) * aName2EnvMap.size() ); - sal_Int32 nSize = 0; - - // find matching environment - for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() ); - iPos != aName2EnvMap.end(); ++iPos ) - { - uno_Environment * pWeak = iPos->second; - if (!rEnvDcp.getLength() || - rEnvDcp.equals( pWeak->pTypeName )) - { - ppFound[nSize] = 0; - (*pWeak->harden)( &ppFound[nSize], pWeak ); - if (ppFound[nSize]) - ++nSize; - } - } - - *pnLen = nSize; - if (nSize) - { - *pppEnvs = (uno_Environment **) (*memAlloc)( - sizeof (uno_Environment *) * nSize ); - OSL_ASSERT( *pppEnvs ); - while (nSize--) - { - (*pppEnvs)[nSize] = ppFound[nSize]; - } - } - else - { - *pppEnvs = 0; - } -} - -static bool loadEnv(OUString const & cLibStem, - uno_Environment * pEnv, - void * /*pContext*/) -{ - // late init with some code from matching uno language binding - // will be unloaded by environment - oslModule hMod = cppu::detail::loadModule( cLibStem ); - - if (!hMod) - return false; - - OUString aSymbolName(RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT)); - uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc) - ::osl_getFunctionSymbol( hMod, aSymbolName.pData ); - if (!fpInit) - { - ::osl_unloadModule( hMod ); - return false; - } - - (*fpInit)( pEnv ); // init of environment - ::rtl_registerModuleForUnloading( hMod ); - - return true; -} - - -extern "C" -{ - -//------------------------------------------------------------------------------ -static uno_Environment * initDefaultEnvironment( - const OUString & rEnvDcp, void * pContext ) -{ - uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase; - (*pEnv->acquire)( pEnv ); - - OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp); - - // create default environment - if (envTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) )) - { - uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv; - that->computeObjectIdentifier = unoenv_computeObjectIdentifier; - that->acquireInterface = unoenv_acquireInterface; - that->releaseInterface = unoenv_releaseInterface; - - OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp); - if (envPurpose.getLength()) - { - rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1); - libStem += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_uno_uno") ); - - if(!loadEnv(libStem, pEnv, pContext)) - { - pEnv->release(pEnv); - return NULL; - } - } - } - else - { - // late init with some code from matching uno language binding - ::rtl::OUStringBuffer aLibName( 16 ); - aLibName.append( envTypeName ); - aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM("_uno" ) ); - OUString aStr( aLibName.makeStringAndClear() ); - - if (!loadEnv(aStr, pEnv, pContext)) - { - pEnv->release(pEnv); - return NULL; - } - } - - return pEnv; -} - -//############################################################################## -void SAL_CALL uno_createEnvironment( - uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) - SAL_THROW_EXTERN_C() -{ - OSL_ENSURE( ppEnv, "### null ptr!" ); - if (*ppEnv) - (*(*ppEnv)->release)( *ppEnv ); - - OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp ); - *ppEnv = initDefaultEnvironment( rEnvDcp, pContext ); -} - -//############################################################################## -void SAL_CALL uno_direct_getEnvironment( - uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext ) - SAL_THROW_EXTERN_C() -{ - OSL_ENSURE( ppEnv, "### null ptr!" ); - OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp ); - - EnvironmentsData & rData = theEnvironmentsData::get(); - - ::osl::MutexGuard guard( rData.mutex ); - rData.getEnvironment( ppEnv, rEnvDcp, pContext ); - if (! *ppEnv) - { - *ppEnv = initDefaultEnvironment( rEnvDcp, pContext ); - if (*ppEnv) - { - // register new environment: - rData.registerEnvironment( ppEnv ); - } - } -} - -//############################################################################## -void SAL_CALL uno_getRegisteredEnvironments( - uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc, - rtl_uString * pEnvDcp ) - SAL_THROW_EXTERN_C() -{ - EnvironmentsData & rData = theEnvironmentsData::get(); - - ::osl::MutexGuard guard( rData.mutex ); - rData.getRegisteredEnvironments( - pppEnvs, pnLen, memAlloc, - (pEnvDcp ? OUString(pEnvDcp) : OUString()) ); -} - -} // extern "C" - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |