Files
libreoffice/cppu/source/uno/lbenv.cxx

1200 lines
39 KiB
C++
Raw Normal View History

2000-09-18 14:29:57 +00:00
/*************************************************************************
*
* $RCSfile: lbenv.cxx,v $
*
* $Revision: 1.29 $
2000-09-18 14:29:57 +00:00
*
* last change: $Author: kz $ $Date: 2004-03-25 14:56:58 $
2000-09-18 14:29:57 +00:00
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
#include "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 "typelib/typedescription.h"
#include "uno/dispatcher.h"
#include "uno/environment.h"
#include "uno/lbnames.h"
2000-09-18 14:29:57 +00:00
#include "prim.hxx"
#include "destr.hxx"
#include <hash_map>
#include <vector>
#include <stdio.h>
2000-09-18 14:29:57 +00:00
using ::rtl::OUString;
2000-09-18 14:29:57 +00:00
namespace
2000-12-21 13:39:29 +00:00
{
//------------------------------------------------------------------------------
inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1,
typelib_InterfaceTypeDescription * pTD2 )
2000-09-18 14:29:57 +00:00
{
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));
2000-09-18 14:29:57 +00:00
}
struct ObjectEntry;
struct uno_DefaultEnvironment;
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
struct InterfaceEntry
{
sal_Int32 refCount;
void * pInterface;
uno_freeProxyFunc fpFreeProxy;
2000-09-18 14:29:57 +00:00
typelib_InterfaceTypeDescription * pTypeDescr;
};
2000-09-18 14:29:57 +00:00
struct ObjectEntry
{
OUString oid;
sal_Int32 nRef;
::std::vector< InterfaceEntry > aInterfaces;
bool mixedObject;
2000-09-18 14:29:57 +00:00
inline ObjectEntry( const OUString & rOId_ );
2000-09-18 14:29:57 +00:00
2000-12-21 13:39:29 +00:00
inline void append(
uno_DefaultEnvironment * pEnv,
2000-12-21 13:39:29 +00:00
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 );
2000-09-18 14:29:57 +00:00
};
//------------------------------------------------------------------------------
struct FctPtrHash :
public ::std::unary_function< const void *, ::std::size_t >
2000-09-18 14:29:57 +00:00
{
::std::size_t operator () ( const void * pKey ) const
{ return (::std::size_t) pKey; }
2000-09-18 14:29:57 +00:00
};
//------------------------------------------------------------------------------
struct FctOUStringHash :
public ::std::unary_function< const OUString &, ::std::size_t >
2000-09-18 14:29:57 +00:00
{
::std::size_t operator () ( const OUString & rKey ) const
2000-09-18 14:29:57 +00:00
{ return rKey.hashCode(); }
};
// mapping from environment name to environment
typedef ::std::hash_map<
OUString, uno_Environment *, FctOUStringHash,
::std::equal_to< OUString > > OUString2EnvironmentMap;
2000-09-18 14:29:57 +00:00
// mapping from ptr to object entry
typedef ::std::hash_map<
void *, ObjectEntry *, FctPtrHash,
::std::equal_to< void * > > Ptr2ObjectMap;
2000-09-18 14:29:57 +00:00
// mapping from oid to object entry
typedef ::std::hash_map<
OUString, ObjectEntry *, FctOUStringHash,
::std::equal_to< OUString > > OId2ObjectMap;
2000-09-18 14:29:57 +00:00
//==============================================================================
2000-09-18 14:29:57 +00:00
struct EnvironmentsData
{
::osl::Mutex mutex;
2000-09-18 14:29:57 +00:00
OUString2EnvironmentMap aName2EnvMap;
~EnvironmentsData();
2000-09-18 14:29:57 +00:00
2001-04-27 07:24:09 +00:00
inline void getEnvironment(
uno_Environment ** ppEnv, const OUString & rTypeName, void * pContext );
inline void registerEnvironment( uno_Environment ** ppEnv );
2000-09-18 14:29:57 +00:00
inline void getRegisteredEnvironments(
uno_Environment *** pppEnvs, sal_Int32 * pnLen,
uno_memAlloc memAlloc, const OUString & rEnvTypeName );
2000-09-18 14:29:57 +00:00
};
//------------------------------------------------------------------------------
static EnvironmentsData & getEnvironmentsData()
2000-09-18 14:29:57 +00:00
{
static EnvironmentsData * s_p = 0;
if (! s_p)
{
::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
2000-09-18 14:29:57 +00:00
if (! s_p)
{
static EnvironmentsData s_obj;
s_p = &s_obj;
}
}
return *s_p;
}
//==============================================================================
2000-09-18 14:29:57 +00:00
struct uno_DefaultEnvironment : public uno_ExtEnvironment
{
sal_Int32 nRef;
sal_Int32 nWeakRef;
2000-09-18 14:29:57 +00:00
::osl::Mutex mutex;
Ptr2ObjectMap aPtr2ObjectMap;
OId2ObjectMap aOId2ObjectMap;
2000-09-18 14:29:57 +00:00
2000-12-21 13:39:29 +00:00
uno_DefaultEnvironment(
const OUString & rTypeName_, void * pContext_ );
~uno_DefaultEnvironment();
2000-09-18 14:29:57 +00:00
};
//______________________________________________________________________________
inline ObjectEntry::ObjectEntry( OUString const & rOId_ )
: oid( rOId_ ),
nRef( 0 ),
mixedObject( false )
2000-09-18 14:29:57 +00:00
{
aInterfaces.reserve( 2 );
2000-09-18 14:29:57 +00:00
}
//______________________________________________________________________________
2000-12-21 13:39:29 +00:00
inline void ObjectEntry::append(
uno_DefaultEnvironment * pEnv,
2000-12-21 13:39:29 +00:00
void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
2001-03-09 11:10:57 +00:00
uno_freeProxyFunc fpFreeProxy )
2000-09-18 14:29:57 +00:00
{
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) );
2000-09-18 14:29:57 +00:00
aInterfaces.push_back( aNewEntry );
}
//______________________________________________________________________________
inline InterfaceEntry * ObjectEntry::find(
typelib_InterfaceTypeDescription * pTypeDescr_ )
2000-09-18 14:29:57 +00:00
{
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") ))
2000-09-18 14:29:57 +00:00
{
return &aInterfaces[ 0 ];
2000-09-18 14:29:57 +00:00
}
::std::size_t nSize = aInterfaces.size();
for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos )
2000-09-18 14:29:57 +00:00
{
typelib_InterfaceTypeDescription * pITD =
aInterfaces[ nPos ].pTypeDescr;
while (pITD)
{
if (td_equals( pITD, pTypeDescr_ ))
return &aInterfaces[ nPos ];
pITD = pITD->pBaseTypeDescription;
}
2000-09-18 14:29:57 +00:00
}
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;
}
2000-12-21 13:39:29 +00:00
extern "C"
{
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_registerInterface(
uno_ExtEnvironment * pEnv, void ** ppInterface,
rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
OUString const & rOId = OUString::unacquired( &pOId );
2000-09-18 14:29:57 +00:00
uno_DefaultEnvironment * that =
static_cast< uno_DefaultEnvironment * >( pEnv );
::osl::ClearableMutexGuard guard( that->mutex );
2000-09-18 14:29:57 +00:00
OId2ObjectMap::const_iterator const iFind(
that->aOId2ObjectMap.find( rOId ) );
if (iFind == that->aOId2ObjectMap.end())
2000-09-18 14:29:57 +00:00
{
ObjectEntry * pOEntry = new ObjectEntry( rOId );
::std::pair< OId2ObjectMap::iterator, bool > insertion(
that->aOId2ObjectMap.insert(
OId2ObjectMap::value_type( rOId, pOEntry ) ) );
OSL_ENSURE( insertion.second,
"### inserting new object entry failed?!" );
2000-09-18 14:29:57 +00:00
++pOEntry->nRef; // another register call on object
pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
2000-09-18 14:29:57 +00:00
}
else // object entry exists
{
ObjectEntry * pOEntry = iFind->second;
2000-09-18 14:29:57 +00:00
++pOEntry->nRef; // another register call on object
InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
2000-09-18 14:29:57 +00:00
if (pIEntry) // type entry exists
{
++pIEntry->refCount;
2000-09-18 14:29:57 +00:00
if (pIEntry->pInterface != *ppInterface)
{
void * pInterface = pIEntry->pInterface;
(*pEnv->acquireInterface)( pEnv, pInterface );
guard.clear();
2000-09-18 14:29:57 +00:00
(*pEnv->releaseInterface)( pEnv, *ppInterface );
*ppInterface = pInterface;
}
}
else
{
pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
2000-09-18 14:29:57 +00:00
}
}
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
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 );
2000-09-18 14:29:57 +00:00
uno_DefaultEnvironment * that =
static_cast< uno_DefaultEnvironment * >( pEnv );
::osl::ClearableMutexGuard guard( that->mutex );
2000-09-18 14:29:57 +00:00
OId2ObjectMap::const_iterator const iFind(
that->aOId2ObjectMap.find( rOId ) );
if (iFind == that->aOId2ObjectMap.end())
2000-09-18 14:29:57 +00:00
{
ObjectEntry * pOEntry = new ObjectEntry( rOId );
::std::pair< OId2ObjectMap::iterator, bool > insertion(
that->aOId2ObjectMap.insert(
OId2ObjectMap::value_type( rOId, pOEntry ) ) );
OSL_ENSURE( insertion.second,
"### inserting new object entry failed?!" );
2000-09-18 14:29:57 +00:00
++pOEntry->nRef; // another register call on object
pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
2000-09-18 14:29:57 +00:00
}
else // object entry exists
{
ObjectEntry * pOEntry = iFind->second;
// first registration was an original, then registerProxyInterface():
pOEntry->mixedObject |=
(!pOEntry->aInterfaces.empty() &&
pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0);
2000-09-18 14:29:57 +00:00
++pOEntry->nRef; // another register call on object
InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
2000-09-18 14:29:57 +00:00
if (pIEntry) // type entry exists
{
if (pIEntry->pInterface == *ppInterface)
{
++pIEntry->refCount;
}
else
2000-09-18 14:29:57 +00:00
{
void * pInterface = pIEntry->pInterface;
(*pEnv->acquireInterface)( pEnv, pInterface );
--pOEntry->nRef; // manual revoke of proxy to be freed
guard.clear();
2000-09-18 14:29:57 +00:00
(*freeProxy)( pEnv, *ppInterface );
*ppInterface = pInterface;
}
}
else
{
pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
2000-09-18 14:29:57 +00:00
}
}
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_revokeInterface(
uno_ExtEnvironment * pEnv, void * pInterface )
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pEnv && pInterface, "### null ptr!" );
uno_DefaultEnvironment * that =
static_cast< uno_DefaultEnvironment * >( pEnv );
::osl::ClearableMutexGuard guard( that->mutex );
2000-09-18 14:29:57 +00:00
Ptr2ObjectMap::const_iterator const iFind(
that->aPtr2ObjectMap.find( pInterface ) );
OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() );
ObjectEntry * pOEntry = iFind->second;
if (! --pOEntry->nRef)
2000-09-18 14:29:57 +00:00
{
// cleanup maps
that->aOId2ObjectMap.erase( pOEntry->oid );
2000-09-18 14:29:57 +00:00
sal_Int32 nPos;
for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
{
that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface );
2000-09-18 14:29:57 +00:00
}
// the last proxy interface of the environment might kill this
// environment, because of releasing its language binding!!!
guard.clear();
2000-09-18 14:29:57 +00:00
// release interfaces
for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
{
InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos];
typelib_typedescription_release(
(typelib_TypeDescription *) rEntry.pTypeDescr );
2000-09-18 14:29:57 +00:00
if (rEntry.fpFreeProxy) // is proxy or used interface?
{
2000-09-18 14:29:57 +00:00
(*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface );
}
2000-09-18 14:29:57 +00:00
else
{
2000-09-18 14:29:57 +00:00
(*pEnv->releaseInterface)( pEnv, rEntry.pInterface );
}
2000-09-18 14:29:57 +00:00
}
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 );
}
}
}
}
2000-09-18 14:29:57 +00:00
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_getObjectIdentifier(
uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
2000-09-18 14:29:57 +00:00
if (*ppOId)
{
::rtl_uString_release( *ppOId );
2000-09-18 14:29:57 +00:00
*ppOId = 0;
}
uno_DefaultEnvironment * that =
static_cast< uno_DefaultEnvironment * >( pEnv );
::osl::ClearableMutexGuard guard( that->mutex );
2000-09-18 14:29:57 +00:00
Ptr2ObjectMap::const_iterator const iFind(
that->aPtr2ObjectMap.find( pInterface ) );
if (iFind == that->aPtr2ObjectMap.end())
2000-09-18 14:29:57 +00:00
{
guard.clear();
(*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface );
2000-09-18 14:29:57 +00:00
}
else
{
rtl_uString * hstr = iFind->second->oid.pData;
rtl_uString_acquire( hstr );
*ppOId = hstr;
2000-09-18 14:29:57 +00:00
}
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_getRegisteredInterface(
uno_ExtEnvironment * pEnv, void ** ppInterface,
rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
2000-09-18 14:29:57 +00:00
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 );
2000-09-18 14:29:57 +00:00
OId2ObjectMap::const_iterator const iFind
( that->aOId2ObjectMap.find( rOId ) );
if (iFind != that->aOId2ObjectMap.end())
2000-09-18 14:29:57 +00:00
{
InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr );
2000-09-18 14:29:57 +00:00
if (pIEntry)
{
(*pEnv->acquireInterface)( pEnv, pIEntry->pInterface );
*ppInterface = pIEntry->pInterface;
}
2000-09-18 14:29:57 +00:00
}
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_getRegisteredInterfaces(
uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen,
uno_memAlloc memAlloc )
2000-09-18 14:29:57 +00:00
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" );
uno_DefaultEnvironment * that =
static_cast< uno_DefaultEnvironment * >( pEnv );
::osl::MutexGuard guard( that->mutex );
2000-09-18 14:29:57 +00:00
sal_Int32 nLen = that->aPtr2ObjectMap.size();
2000-09-18 14:29:57 +00:00
sal_Int32 nPos = 0;
void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) );
2000-09-18 14:29:57 +00:00
Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() );
Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() );
2001-04-27 07:24:09 +00:00
while (iPos != iEnd)
2000-09-18 14:29:57 +00:00
{
(*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first );
++iPos;
}
*pppInterfaces = ppInterfaces;
*pnLen = nLen;
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_acquire( uno_Environment * pEnv )
{
2001-04-27 07:24:09 +00:00
uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
::osl_incrementInterlockedCount( &that->nWeakRef );
::osl_incrementInterlockedCount( &that->nRef );
2000-09-18 14:29:57 +00:00
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_release( uno_Environment * pEnv )
{
2001-04-27 07:24:09 +00:00
uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
if (! ::osl_decrementInterlockedCount( &that->nRef ))
2000-09-18 14:29:57 +00:00
{
2001-04-27 07:24:09 +00:00
// 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;
}
}
//------------------------------------------------------------------------------
2001-04-27 07:24:09 +00:00
static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv )
{
uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
::osl_incrementInterlockedCount( &that->nWeakRef );
}
//------------------------------------------------------------------------------
2001-04-27 07:24:09 +00:00
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 )
2001-04-27 07:24:09 +00:00
{
if (*ppHardEnv)
{
(*(*ppHardEnv)->release)( *ppHardEnv );
*ppHardEnv = 0;
}
uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
{
::osl::MutexGuard guard( getEnvironmentsData().mutex );
2001-04-27 07:24:09 +00:00
if (1 == ::osl_incrementInterlockedCount( &that->nRef )) // is dead
{
that->nRef = 0;
return;
2000-09-18 14:29:57 +00:00
}
2001-04-27 07:24:09 +00:00
}
::osl_incrementInterlockedCount( &that->nWeakRef );
*ppHardEnv = pEnv;
2000-09-18 14:29:57 +00:00
}
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL defenv_dispose( uno_Environment * pEnv )
{
}
2000-12-21 13:39:29 +00:00
}
2000-09-18 14:29:57 +00:00
//______________________________________________________________________________
2000-09-18 14:29:57 +00:00
uno_DefaultEnvironment::uno_DefaultEnvironment(
const OUString & rTypeName_, void * pContext_ )
: nRef( 0 ),
nWeakRef( 0 )
2000-09-18 14:29:57 +00:00
{
uno_Environment * that = reinterpret_cast< uno_Environment * >(this);
that->pReserved = 0;
2000-09-18 14:29:57 +00:00
// 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;
2000-09-18 14:29:57 +00:00
// identifier
::rtl_uString_acquire( rTypeName_.pData );
that->pTypeName = rTypeName_.pData;
that->pContext = pContext_;
2000-09-18 14:29:57 +00:00
// will be late initialized
that->environmentDisposing = 0;
2000-09-18 14:29:57 +00:00
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;
2000-09-18 14:29:57 +00:00
}
//______________________________________________________________________________
uno_DefaultEnvironment::~uno_DefaultEnvironment()
2000-09-18 14:29:57 +00:00
{
::rtl_uString_release( ((uno_Environment *) this)->pTypeName );
2000-09-18 14:29:57 +00:00
}
//==============================================================================
static void writeLine(
void * stream, const sal_Char * pLine, const sal_Char * pFilter )
2000-09-18 14:29:57 +00:00
{
if (pFilter && *pFilter)
{
// lookup pFilter in pLine
while (*pLine)
{
if (*pLine == *pFilter)
{
sal_Int32 nPos = 1;
while (pLine[nPos] && pFilter[nPos] == pLine[nPos])
2001-04-27 07:24:09 +00:00
{
2000-09-18 14:29:57 +00:00
++nPos;
2001-04-27 07:24:09 +00:00
}
2000-09-18 14:29:57 +00:00
if (! pFilter[nPos])
{
if (stream)
{
fprintf( (FILE *) stream, "%s\n", pLine );
2000-09-18 14:29:57 +00:00
}
else
{
OSL_TRACE( pLine );
OSL_TRACE( "\n" );
}
}
}
++pLine;
}
}
else
{
if (stream)
{
fprintf( (FILE *) stream, "%s\n", pLine );
2000-09-18 14:29:57 +00:00
}
else
{
fprintf( stderr, "%s\n", pLine );
2000-09-18 14:29:57 +00:00
}
}
}
//==============================================================================
static void writeLine(
void * stream, const OUString & rLine, const sal_Char * pFilter )
2000-09-18 14:29:57 +00:00
{
::rtl::OString aLine( ::rtl::OUStringToOString(
rLine, RTL_TEXTENCODING_ASCII_US ) );
2000-09-18 14:29:57 +00:00
writeLine( stream, aLine.getStr(), pFilter );
}
//##############################################################################
extern "C" void SAL_CALL uno_dumpEnvironment(
2001-03-09 11:10:57 +00:00
void * stream, uno_Environment * pEnv, const sal_Char * pFilter )
2002-08-19 12:02:55 +00:00
SAL_THROW_EXTERN_C()
2000-09-18 14:29:57 +00:00
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pEnv, "### null ptr!" );
::rtl::OUStringBuffer buf;
2000-09-18 14:29:57 +00:00
if (! pEnv->pExtEnv)
{
writeLine( stream, "###################################"
"###########################################", pFilter );
2000-09-18 14:29:57 +00:00
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 );
2000-09-18 14:29:57 +00:00
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 );
2000-09-18 14:29:57 +00:00
Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap );
OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() );
while (iPos != that->aOId2ObjectMap.end())
2000-09-18 14:29:57 +00:00
{
ObjectEntry * pOEntry = iPos->second;
2000-09-18 14:29:57 +00:00
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ") );
if (pOEntry->mixedObject)
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ") );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=") );
2000-09-18 14:29:57 +00:00
buf.append( pOEntry->nRef, 10 );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"") );
buf.append( pOEntry->oid );
buf.append( (sal_Unicode) '\"' );
2000-09-18 14:29:57 +00:00
writeLine( stream, buf.makeStringAndClear(), pFilter );
for ( ::std::size_t nPos = 0;
nPos < pOEntry->aInterfaces.size(); ++nPos )
2000-09-18 14:29:57 +00:00
{
const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos];
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" - ") );
buf.append(
((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName );
2000-09-18 14:29:57 +00:00
if (rIEntry.fpFreeProxy)
{
buf.appendAscii(
RTL_CONSTASCII_STRINGPARAM("; proxy free=0x") );
2000-09-18 14:29:57 +00:00
buf.append( (sal_Int64)rIEntry.fpFreeProxy, 16 );
}
else
{
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original") );
}
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x") );
buf.append( (sal_Int64) 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!)") );
}
}
2000-09-18 14:29:57 +00:00
writeLine( stream, buf.makeStringAndClear(), pFilter );
}
++iPos;
}
if (! ptr2obj.empty())
writeLine( stream, "ptr map inconsistency!!!", pFilter );
writeLine( stream, "#####################################"
"#########################################", pFilter );
2000-09-18 14:29:57 +00:00
}
//##############################################################################
extern "C" void SAL_CALL uno_dumpEnvironmentByName(
2001-03-09 11:10:57 +00:00
void * stream, rtl_uString * pEnvTypeName, const sal_Char * pFilter )
2002-08-19 12:02:55 +00:00
SAL_THROW_EXTERN_C()
2000-09-18 14:29:57 +00:00
{
uno_Environment * pEnv = 0;
uno_getEnvironment( &pEnv, pEnvTypeName, 0 );
if (pEnv)
{
2001-01-15 16:29:00 +00:00
::uno_dumpEnvironment( stream, pEnv, pFilter );
2000-09-18 14:29:57 +00:00
(*pEnv->release)( pEnv );
}
else
{
::rtl::OUStringBuffer buf( 32 );
2000-09-18 14:29:57 +00:00
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"") );
buf.append( pEnvTypeName );
buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!") );
writeLine( stream, buf.makeStringAndClear(), pFilter );
}
}
//------------------------------------------------------------------------------
2001-03-09 11:10:57 +00:00
inline static const OUString & unoenv_getStaticOIdPart()
2000-09-18 14:29:57 +00:00
{
static OUString * s_pStaticOidPart = 0;
if (! s_pStaticOidPart)
{
::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
2000-09-18 14:29:57 +00:00
if (! s_pStaticOidPart)
{
::rtl::OUStringBuffer aRet( 64 );
2000-09-18 14:29:57 +00:00
aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
// pid
oslProcessInfo info;
info.Size = sizeof(oslProcessInfo);
if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) ==
osl_Process_E_None)
{
2000-09-18 14:29:57 +00:00
aRet.append( (sal_Int64)info.Ident, 16 );
}
2000-09-18 14:29:57 +00:00
else
{
aRet.appendAscii(
RTL_CONSTASCII_STRINGPARAM("unknown process id") );
}
2000-09-18 14:29:57 +00:00
// good guid
sal_uInt8 ar[16];
::rtl_getGlobalProcessId( ar );
2000-09-18 14:29:57 +00:00
aRet.append( (sal_Unicode)';' );
for ( sal_Int32 i = 0; i < 16; ++i )
aRet.append( (sal_Int32)ar[i], 16 );
static OUString s_aStaticOidPart( aRet.makeStringAndClear() );
s_pStaticOidPart = &s_aStaticOidPart;
}
}
return *s_pStaticOidPart;
}
2000-12-21 13:39:29 +00:00
extern "C"
{
//------------------------------------------------------------------------------
2000-09-18 14:29:57 +00:00
static void SAL_CALL unoenv_computeObjectIdentifier(
2001-03-09 11:10:57 +00:00
uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
2000-09-18 14:29:57 +00:00
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
2000-09-18 14:29:57 +00:00
if (*ppOId)
{
::rtl_uString_release( *ppOId );
2000-09-18 14:29:57 +00:00
*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 );
2000-09-18 14:29:57 +00:00
}
}
//==============================================================================
static void SAL_CALL unoenv_acquireInterface(
uno_ExtEnvironment *, void * pUnoI_ )
2000-09-18 14:29:57 +00:00
{
uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
(*pUnoI->acquire)( pUnoI );
2000-09-18 14:29:57 +00:00
}
//==============================================================================
static void SAL_CALL unoenv_releaseInterface(
uno_ExtEnvironment *, void * pUnoI_ )
2000-09-18 14:29:57 +00:00
{
uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
(*pUnoI->release)( pUnoI );
2000-09-18 14:29:57 +00:00
}
2000-12-21 13:39:29 +00:00
}
2000-09-18 14:29:57 +00:00
//______________________________________________________________________________
EnvironmentsData::~EnvironmentsData()
2000-09-18 14:29:57 +00:00
{
::osl::MutexGuard guard( mutex );
2000-09-18 14:29:57 +00:00
2001-04-27 07:24:09 +00:00
for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
iPos != aName2EnvMap.end(); ++iPos )
2000-09-18 14:29:57 +00:00
{
2001-04-27 07:24:09 +00:00
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 );
2000-09-18 14:29:57 +00:00
#endif
#if defined CPPU_LEAK_STATIC_DATA
2001-04-27 07:24:09 +00:00
pHard->environmentDisposing = 0; // set to null => wont be called
#else
2001-04-27 07:24:09 +00:00
(*pHard->dispose)( pHard ); // send explicit dispose
#endif
2001-04-27 07:24:09 +00:00
(*pHard->release)( pHard );
}
2000-09-18 14:29:57 +00:00
}
}
//______________________________________________________________________________
2001-04-27 07:24:09 +00:00
inline void EnvironmentsData::getEnvironment(
uno_Environment ** ppEnv, const OUString & rEnvTypeName, void * pContext )
2000-09-18 14:29:57 +00:00
{
2001-04-27 07:24:09 +00:00
if (*ppEnv)
{
(*(*ppEnv)->release)( *ppEnv );
*ppEnv = 0;
}
2000-09-18 14:29:57 +00:00
2001-10-18 11:39:56 +00:00
OUString aKey( OUString::valueOf( (sal_Int64)pContext ) );
2000-09-18 14:29:57 +00:00
aKey += rEnvTypeName;
// try to find registered mapping
OUString2EnvironmentMap::const_iterator const iFind(
aName2EnvMap.find( aKey ) );
2000-09-18 14:29:57 +00:00
if (iFind != aName2EnvMap.end())
{
2001-04-27 07:24:09 +00:00
uno_Environment * pWeak = iFind->second;
(*pWeak->harden)( ppEnv, pWeak );
2000-09-18 14:29:57 +00:00
}
}
//______________________________________________________________________________
2001-04-27 07:24:09 +00:00
inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv )
2000-09-18 14:29:57 +00:00
{
2001-04-27 07:24:09 +00:00
OSL_ENSURE( ppEnv, "### null ptr!" );
uno_Environment * pEnv = *ppEnv;
2000-09-18 14:29:57 +00:00
OUString aKey( OUString::valueOf( (sal_Int64)pEnv->pContext ) );
aKey += pEnv->pTypeName;
2001-04-27 07:24:09 +00:00
// try to find registered environment
OUString2EnvironmentMap::const_iterator const iFind(
aName2EnvMap.find( aKey ) );
2000-09-18 14:29:57 +00:00
if (iFind == aName2EnvMap.end())
{
2001-04-27 07:24:09 +00:00
(*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?!" );
2000-09-18 14:29:57 +00:00
}
2001-04-27 07:24:09 +00:00
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;
}
}
2000-09-18 14:29:57 +00:00
}
//______________________________________________________________________________
2000-09-18 14:29:57 +00:00
inline void EnvironmentsData::getRegisteredEnvironments(
uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
2001-03-09 11:10:57 +00:00
const OUString & rEnvTypeName )
2000-09-18 14:29:57 +00:00
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" );
2000-09-18 14:29:57 +00:00
// max size
2001-04-27 07:24:09 +00:00
uno_Environment ** ppFound = (uno_Environment **)alloca(
sizeof(uno_Environment *) * aName2EnvMap.size() );
sal_Int32 nSize = 0;
2000-09-18 14:29:57 +00:00
// find matching environment
for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
iPos != aName2EnvMap.end(); ++iPos )
{
2001-04-27 07:24:09 +00:00
uno_Environment * pWeak = iPos->second;
if (!rEnvTypeName.getLength() ||
rEnvTypeName.equals( pWeak->pTypeName ))
2000-09-18 14:29:57 +00:00
{
2001-04-27 07:24:09 +00:00
ppFound[nSize] = 0;
(*pWeak->harden)( &ppFound[nSize], pWeak );
if (ppFound[nSize])
++nSize;
2000-09-18 14:29:57 +00:00
}
}
*pnLen = nSize;
if (nSize)
{
*pppEnvs = (uno_Environment **) (*memAlloc)(
sizeof (uno_Environment *) * nSize );
2000-09-18 14:29:57 +00:00
OSL_ASSERT( *pppEnvs );
while (nSize--)
{
(*pppEnvs)[nSize] = ppFound[nSize];
}
}
else
{
*pppEnvs = 0;
}
}
2001-04-27 07:24:09 +00:00
2000-12-21 13:39:29 +00:00
extern "C"
{
//------------------------------------------------------------------------------
2000-12-21 13:39:29 +00:00
static uno_Environment * initDefaultEnvironment(
2001-03-09 11:10:57 +00:00
const OUString & rEnvTypeName, void * pContext )
2000-09-18 14:29:57 +00:00
{
uno_Environment * pEnv = 0;
// create default environment
if (rEnvTypeName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_LB_UNO) ))
{
uno_DefaultEnvironment * that = new uno_DefaultEnvironment(
rEnvTypeName, pContext );
2001-04-27 07:24:09 +00:00
pEnv = (uno_Environment *)that;
2000-09-18 14:29:57 +00:00
(*pEnv->acquire)( pEnv );
2001-04-27 07:24:09 +00:00
that->computeObjectIdentifier = unoenv_computeObjectIdentifier;
that->acquireInterface = unoenv_acquireInterface;
that->releaseInterface = unoenv_releaseInterface;
2000-09-18 14:29:57 +00:00
}
else
{
// late init with some code from matching uno language binding
::rtl::OUStringBuffer aLibName( 16 );
#if defined SAL_DLLPREFIX
aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM(SAL_DLLPREFIX) );
#endif
2000-09-18 14:29:57 +00:00
aLibName.append( rEnvTypeName );
aLibName.appendAscii(
RTL_CONSTASCII_STRINGPARAM("_uno" SAL_DLLEXTENSION) );
2000-09-18 14:29:57 +00:00
OUString aStr( aLibName.makeStringAndClear() );
// will be unloaded by environment
oslModule hMod = ::osl_loadModule(
aStr.pData, SAL_LOADMODULE_GLOBAL | SAL_LOADMODULE_LAZY );
2000-09-18 14:29:57 +00:00
if (hMod)
{
OUString aSymbolName(
RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT) );
uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc)
::osl_getSymbol( hMod, aSymbolName.pData );
2000-09-18 14:29:57 +00:00
if (fpInit)
{
pEnv = reinterpret_cast< uno_Environment * >(
new uno_DefaultEnvironment(
rEnvTypeName, pContext ) );
2000-09-18 14:29:57 +00:00
(*pEnv->acquire)( pEnv );
(*fpInit)( pEnv ); // init of environment
::rtl_registerModuleForUnloading( hMod );
2000-09-18 14:29:57 +00:00
}
else
{
::osl_unloadModule( hMod );
2000-09-18 14:29:57 +00:00
}
}
}
return pEnv;
}
//##############################################################################
void SAL_CALL uno_createEnvironment(
2001-03-09 11:10:57 +00:00
uno_Environment ** ppEnv, rtl_uString * pEnvTypeName, void * pContext )
SAL_THROW_EXTERN_C()
2000-09-18 14:29:57 +00:00
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( ppEnv, "### null ptr!" );
2000-09-18 14:29:57 +00:00
if (*ppEnv)
(*(*ppEnv)->release)( *ppEnv );
OUString const & rEnvTypeName = OUString::unacquired( &pEnvTypeName );
2001-04-27 07:24:09 +00:00
*ppEnv = initDefaultEnvironment( rEnvTypeName, pContext );
2000-09-18 14:29:57 +00:00
}
//##############################################################################
void SAL_CALL uno_getEnvironment(
2001-03-09 11:10:57 +00:00
uno_Environment ** ppEnv, rtl_uString * pEnvTypeName, void * pContext )
SAL_THROW_EXTERN_C()
2000-09-18 14:29:57 +00:00
{
2001-03-12 12:28:14 +00:00
OSL_ENSURE( ppEnv, "### null ptr!" );
2000-09-18 14:29:57 +00:00
if (*ppEnv)
(*(*ppEnv)->release)( *ppEnv );
OUString const & rEnvTypeName = OUString::unacquired( &pEnvTypeName );
2000-09-18 14:29:57 +00:00
2001-04-27 07:24:09 +00:00
EnvironmentsData & rData = getEnvironmentsData();
2000-09-18 14:29:57 +00:00
::osl::MutexGuard guard( rData.mutex );
2001-04-27 07:24:09 +00:00
rData.getEnvironment( ppEnv, rEnvTypeName, pContext );
2000-09-18 14:29:57 +00:00
if (! *ppEnv)
{
if (*ppEnv = initDefaultEnvironment( rEnvTypeName, pContext ))
2001-04-27 07:24:09 +00:00
{
// register new environment:
2001-04-27 07:24:09 +00:00
rData.registerEnvironment( ppEnv );
}
2000-09-18 14:29:57 +00:00
}
}
//##############################################################################
void SAL_CALL uno_getRegisteredEnvironments(
2000-09-18 14:29:57 +00:00
uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
2001-03-09 11:10:57 +00:00
rtl_uString * pEnvTypeName )
SAL_THROW_EXTERN_C()
2000-09-18 14:29:57 +00:00
{
2001-04-27 07:24:09 +00:00
EnvironmentsData & rData = getEnvironmentsData();
::osl::MutexGuard guard( rData.mutex );
2001-04-27 07:24:09 +00:00
rData.getRegisteredEnvironments(
2000-09-18 14:29:57 +00:00
pppEnvs, pnLen, memAlloc,
(pEnvTypeName ? OUString(pEnvTypeName) : OUString()) );
2000-09-18 14:29:57 +00:00
}
2001-03-09 11:10:57 +00:00
} // extern "C"
2000-12-21 13:39:29 +00:00
}