LCOV - code coverage report
Current view: top level - cppu/source/uno - lbenv.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 132 491 26.9 %
Date: 2014-04-14 Functions: 15 44 34.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : 
      22             : #include "cppu/EnvDcp.hxx"
      23             : 
      24             : #include "sal/alloca.h"
      25             : #include "sal/log.hxx"
      26             : #include "osl/diagnose.h"
      27             : #include "osl/interlck.h"
      28             : #include "osl/mutex.hxx"
      29             : #include "osl/module.h"
      30             : #include "osl/process.h"
      31             : #include "rtl/process.h"
      32             : #include "rtl/string.hxx"
      33             : #include "rtl/ustring.hxx"
      34             : #include "rtl/ustrbuf.hxx"
      35             : #include "rtl/instance.hxx"
      36             : #include "typelib/typedescription.h"
      37             : #include "uno/dispatcher.h"
      38             : #include "uno/environment.h"
      39             : #include "uno/lbnames.h"
      40             : #include "prim.hxx"
      41             : #include "destr.hxx"
      42             : #include "loadmodule.hxx"
      43             : 
      44             : #include <boost/unordered_map.hpp>
      45             : #include <vector>
      46             : #include <stdio.h>
      47             : 
      48             : 
      49             : using ::rtl::OUString;
      50             : 
      51             : namespace
      52             : {
      53             : 
      54             : 
      55           0 : inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1,
      56             :                               typelib_InterfaceTypeDescription * pTD2 )
      57             : {
      58           0 :     return (pTD1 == pTD2 ||
      59           0 :             (((typelib_TypeDescription *)pTD1)->pTypeName->length ==
      60           0 :              ((typelib_TypeDescription *)pTD2)->pTypeName->length &&
      61             :              ::rtl_ustr_compare(
      62             :                  ((typelib_TypeDescription *) pTD1)->pTypeName->buffer,
      63           0 :                  ((typelib_TypeDescription *) pTD2)->pTypeName->buffer ) == 0));
      64             : }
      65             : 
      66             : struct ObjectEntry;
      67             : struct uno_DefaultEnvironment;
      68             : 
      69             : 
      70             : struct InterfaceEntry
      71             : {
      72             :     sal_Int32 refCount;
      73             :     void * pInterface;
      74             :     uno_freeProxyFunc fpFreeProxy;
      75             :     typelib_InterfaceTypeDescription * pTypeDescr;
      76             : };
      77             : 
      78           0 : struct ObjectEntry
      79             : {
      80             :     OUString oid;
      81             :     sal_Int32 nRef;
      82             :     ::std::vector< InterfaceEntry > aInterfaces;
      83             :     bool mixedObject;
      84             : 
      85             :     inline ObjectEntry( const OUString & rOId_ );
      86             : 
      87             :     inline void append(
      88             :         uno_DefaultEnvironment * pEnv,
      89             :         void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
      90             :         uno_freeProxyFunc fpFreeProxy );
      91             :     inline InterfaceEntry * find(
      92             :         typelib_InterfaceTypeDescription * pTypeDescr );
      93             :     inline sal_Int32 find( void * iface_ptr, ::std::size_t pos );
      94             : };
      95             : 
      96             : 
      97             : struct FctPtrHash :
      98             :     public ::std::unary_function< const void *, ::std::size_t >
      99             : {
     100           0 :     ::std::size_t operator () ( const void * pKey ) const
     101           0 :         { return (::std::size_t) pKey; }
     102             : };
     103             : 
     104             : 
     105             : struct FctOUStringHash :
     106             :     public ::std::unary_function< const OUString &, ::std::size_t >
     107             : {
     108          25 :     ::std::size_t operator () ( const OUString & rKey ) const
     109          25 :         { return rKey.hashCode(); }
     110             : };
     111             : 
     112             : // mapping from environment name to environment
     113             : typedef ::boost::unordered_map<
     114             :     OUString, uno_Environment *, FctOUStringHash,
     115             :     ::std::equal_to< OUString > > OUString2EnvironmentMap;
     116             : 
     117             : // mapping from ptr to object entry
     118             : typedef ::boost::unordered_map<
     119             :     void *, ObjectEntry *, FctPtrHash,
     120             :     ::std::equal_to< void * > > Ptr2ObjectMap;
     121             : // mapping from oid to object entry
     122             : typedef ::boost::unordered_map<
     123             :     OUString, ObjectEntry *, FctOUStringHash,
     124             :     ::std::equal_to< OUString > > OId2ObjectMap;
     125             : 
     126             : 
     127             : 
     128             : struct EnvironmentsData
     129             : {
     130             :     ::osl::Mutex mutex;
     131             :     OUString2EnvironmentMap aName2EnvMap;
     132             : 
     133           1 :     EnvironmentsData() : isDisposing(false) {}
     134             :     ~EnvironmentsData();
     135             : 
     136             :     inline void getEnvironment(
     137             :         uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext );
     138             :     inline void registerEnvironment( uno_Environment ** ppEnv );
     139             :     inline void getRegisteredEnvironments(
     140             :         uno_Environment *** pppEnvs, sal_Int32 * pnLen,
     141             :         uno_memAlloc memAlloc, const OUString & rEnvDcp );
     142             : 
     143             :     bool isDisposing;
     144             : };
     145             : 
     146             : namespace
     147             : {
     148             :     struct theEnvironmentsData : public rtl::Static< EnvironmentsData, theEnvironmentsData > {};
     149             : }
     150             : 
     151             : 
     152             : struct uno_DefaultEnvironment : public uno_ExtEnvironment
     153             : {
     154             :     sal_Int32 nRef;
     155             :     sal_Int32 nWeakRef;
     156             : 
     157             :     ::osl::Mutex mutex;
     158             :     Ptr2ObjectMap aPtr2ObjectMap;
     159             :     OId2ObjectMap aOId2ObjectMap;
     160             : 
     161             :     uno_DefaultEnvironment(
     162             :         const OUString & rEnvDcp_, void * pContext_ );
     163             :     ~uno_DefaultEnvironment();
     164             : };
     165             : 
     166             : 
     167           0 : inline ObjectEntry::ObjectEntry( OUString const & rOId_ )
     168             :     : oid( rOId_ ),
     169             :       nRef( 0 ),
     170           0 :       mixedObject( false )
     171             : {
     172           0 :     aInterfaces.reserve( 2 );
     173           0 : }
     174             : 
     175             : 
     176           0 : inline void ObjectEntry::append(
     177             :     uno_DefaultEnvironment * pEnv,
     178             :     void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
     179             :     uno_freeProxyFunc fpFreeProxy )
     180             : {
     181             :     InterfaceEntry aNewEntry;
     182           0 :     if (! fpFreeProxy)
     183           0 :         (*pEnv->acquireInterface)( pEnv, pInterface );
     184           0 :     aNewEntry.refCount = 1;
     185           0 :     aNewEntry.pInterface = pInterface;
     186           0 :     aNewEntry.fpFreeProxy = fpFreeProxy;
     187           0 :     typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr );
     188           0 :     aNewEntry.pTypeDescr = pTypeDescr;
     189             : 
     190             :     ::std::pair< Ptr2ObjectMap::iterator, bool > i(
     191             :         pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type(
     192           0 :                                          pInterface, this ) ) );
     193             :     SAL_WARN_IF(
     194             :         !i.second && (find(pInterface, 0) == -1 || i.first->second != this),
     195             :         "cppu",
     196             :         "map already contains " << i.first->second << " != " << this << " for "
     197             :             << pInterface);
     198           0 :     aInterfaces.push_back( aNewEntry );
     199           0 : }
     200             : 
     201             : 
     202           0 : inline InterfaceEntry * ObjectEntry::find(
     203             :     typelib_InterfaceTypeDescription * pTypeDescr_ )
     204             : {
     205             :     OSL_ASSERT( ! aInterfaces.empty() );
     206           0 :     if (aInterfaces.empty())
     207           0 :         return 0;
     208             : 
     209             :     // shortcut common case:
     210             :     OUString const & type_name =
     211             :         OUString::unacquired(
     212           0 :             &((typelib_TypeDescription *) pTypeDescr_)->pTypeName );
     213           0 :     if ( type_name == "com.sun.star.uno.XInterface" )
     214             :     {
     215           0 :         return &aInterfaces[ 0 ];
     216             :     }
     217             : 
     218           0 :     ::std::size_t nSize = aInterfaces.size();
     219           0 :     for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos )
     220             :     {
     221             :         typelib_InterfaceTypeDescription * pITD =
     222           0 :             aInterfaces[ nPos ].pTypeDescr;
     223           0 :         while (pITD)
     224             :         {
     225           0 :             if (td_equals( pITD, pTypeDescr_ ))
     226           0 :                 return &aInterfaces[ nPos ];
     227           0 :             pITD = pITD->pBaseTypeDescription;
     228             :         }
     229             :     }
     230           0 :     return 0;
     231             : }
     232             : 
     233             : 
     234           0 : inline sal_Int32 ObjectEntry::find(
     235             :     void * iface_ptr, ::std::size_t pos )
     236             : {
     237           0 :     ::std::size_t size = aInterfaces.size();
     238           0 :     for ( ; pos < size; ++pos )
     239             :     {
     240           0 :         if (aInterfaces[ pos ].pInterface == iface_ptr)
     241           0 :             return pos;
     242             :     }
     243           0 :     return -1;
     244             : }
     245             : 
     246             : extern "C"
     247             : {
     248             : 
     249             : 
     250           0 : static void SAL_CALL defenv_registerInterface(
     251             :     uno_ExtEnvironment * pEnv, void ** ppInterface,
     252             :     rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
     253             : {
     254             :     OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
     255           0 :     OUString const & rOId = OUString::unacquired( &pOId );
     256             : 
     257             :     uno_DefaultEnvironment * that =
     258           0 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     259           0 :     ::osl::ClearableMutexGuard guard( that->mutex );
     260             : 
     261             :     // try to insert dummy 0:
     262             :     std::pair<OId2ObjectMap::iterator, bool> const insertion(
     263           0 :         that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) );
     264           0 :     if (insertion.second)
     265             :     {
     266           0 :         ObjectEntry * pOEntry = new ObjectEntry( rOId );
     267           0 :         insertion.first->second = pOEntry;
     268           0 :         ++pOEntry->nRef; // another register call on object
     269           0 :         pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
     270             :     }
     271             :     else // object entry exists
     272             :     {
     273           0 :         ObjectEntry * pOEntry = insertion.first->second;
     274           0 :         ++pOEntry->nRef; // another register call on object
     275           0 :         InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
     276             : 
     277           0 :         if (pIEntry) // type entry exists
     278             :         {
     279           0 :             ++pIEntry->refCount;
     280           0 :             if (pIEntry->pInterface != *ppInterface)
     281             :             {
     282           0 :                 void * pInterface = pIEntry->pInterface;
     283           0 :                 (*pEnv->acquireInterface)( pEnv, pInterface );
     284           0 :                 guard.clear();
     285           0 :                 (*pEnv->releaseInterface)( pEnv, *ppInterface );
     286           0 :                 *ppInterface = pInterface;
     287             :             }
     288             :         }
     289             :         else
     290             :         {
     291           0 :             pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
     292             :         }
     293           0 :     }
     294           0 : }
     295             : 
     296             : 
     297           0 : static void SAL_CALL defenv_registerProxyInterface(
     298             :     uno_ExtEnvironment * pEnv, void ** ppInterface, uno_freeProxyFunc freeProxy,
     299             :     rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
     300             : {
     301             :     OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr && freeProxy,
     302             :                 "### null ptr!" );
     303           0 :     OUString const & rOId = OUString::unacquired( &pOId );
     304             : 
     305             :     uno_DefaultEnvironment * that =
     306           0 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     307           0 :     ::osl::ClearableMutexGuard guard( that->mutex );
     308             : 
     309             :     // try to insert dummy 0:
     310             :     std::pair<OId2ObjectMap::iterator, bool> const insertion(
     311           0 :         that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) );
     312           0 :     if (insertion.second)
     313             :     {
     314           0 :         ObjectEntry * pOEntry = new ObjectEntry( rOId );
     315           0 :         insertion.first->second = pOEntry;
     316           0 :         ++pOEntry->nRef; // another register call on object
     317           0 :         pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
     318             :     }
     319             :     else // object entry exists
     320             :     {
     321           0 :         ObjectEntry * pOEntry = insertion.first->second;
     322             : 
     323             :         // first registration was an original, then registerProxyInterface():
     324             :         pOEntry->mixedObject |=
     325           0 :             (!pOEntry->aInterfaces.empty() &&
     326           0 :              pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0);
     327             : 
     328           0 :         ++pOEntry->nRef; // another register call on object
     329           0 :         InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
     330             : 
     331           0 :         if (pIEntry) // type entry exists
     332             :         {
     333           0 :             if (pIEntry->pInterface == *ppInterface)
     334             :             {
     335           0 :                 ++pIEntry->refCount;
     336             :             }
     337             :             else
     338             :             {
     339           0 :                 void * pInterface = pIEntry->pInterface;
     340           0 :                 (*pEnv->acquireInterface)( pEnv, pInterface );
     341           0 :                 --pOEntry->nRef; // manual revoke of proxy to be freed
     342           0 :                 guard.clear();
     343           0 :                 (*freeProxy)( pEnv, *ppInterface );
     344           0 :                 *ppInterface = pInterface;
     345             :             }
     346             :         }
     347             :         else
     348             :         {
     349           0 :             pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
     350             :         }
     351           0 :     }
     352           0 : }
     353             : 
     354             : 
     355           0 : static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam)
     356             : {
     357           0 :     uno_ExtEnvironment * pEnv       = va_arg(*pParam, uno_ExtEnvironment *);
     358           0 :     void               * pInterface = va_arg(*pParam, void *);
     359             : 
     360             :     OSL_ENSURE( pEnv && pInterface, "### null ptr!" );
     361             :     uno_DefaultEnvironment * that =
     362           0 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     363           0 :     ::osl::ClearableMutexGuard guard( that->mutex );
     364             : 
     365             :     Ptr2ObjectMap::const_iterator const iFind(
     366           0 :         that->aPtr2ObjectMap.find( pInterface ) );
     367             :     OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() );
     368           0 :     ObjectEntry * pOEntry = iFind->second;
     369           0 :     if (! --pOEntry->nRef)
     370             :     {
     371             :         // cleanup maps
     372           0 :         that->aOId2ObjectMap.erase( pOEntry->oid );
     373             :         sal_Int32 nPos;
     374           0 :         for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
     375             :         {
     376           0 :             that->aPtr2ObjectMap.erase( pOEntry->aInterfaces[nPos].pInterface );
     377             :         }
     378             : 
     379             :         // the last proxy interface of the environment might kill this
     380             :         // environment, because of releasing its language binding!!!
     381           0 :         guard.clear();
     382             : 
     383             :         // release interfaces
     384           0 :         for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
     385             :         {
     386           0 :             InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos];
     387             :             typelib_typedescription_release(
     388           0 :                 (typelib_TypeDescription *) rEntry.pTypeDescr );
     389           0 :             if (rEntry.fpFreeProxy) // is proxy or used interface?
     390             :             {
     391           0 :                 (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface );
     392             :             }
     393             :             else
     394             :             {
     395           0 :                 (*pEnv->releaseInterface)( pEnv, rEntry.pInterface );
     396             :             }
     397             :         }
     398             : 
     399           0 :         delete pOEntry;
     400             :     }
     401           0 :     else if (pOEntry->mixedObject)
     402             :     {
     403             :         OSL_ASSERT( !pOEntry->aInterfaces.empty() &&
     404             :                     pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0 );
     405             : 
     406           0 :         sal_Int32 index = pOEntry->find( pInterface, 1 );
     407             :         OSL_ASSERT( index > 0 );
     408           0 :         if (index > 0)
     409             :         {
     410           0 :             InterfaceEntry & entry = pOEntry->aInterfaces[ index ];
     411             :             OSL_ASSERT( entry.pInterface == pInterface );
     412           0 :             if (entry.fpFreeProxy != 0)
     413             :             {
     414           0 :                 --entry.refCount;
     415           0 :                 if (entry.refCount == 0)
     416             :                 {
     417           0 :                     uno_freeProxyFunc fpFreeProxy = entry.fpFreeProxy;
     418             :                     typelib_TypeDescription * pTypeDescr =
     419             :                         reinterpret_cast< typelib_TypeDescription * >(
     420           0 :                             entry.pTypeDescr );
     421             : 
     422             :                     pOEntry->aInterfaces.erase(
     423           0 :                         pOEntry->aInterfaces.begin() + index );
     424           0 :                     if (pOEntry->find( pInterface, index ) < 0)
     425             :                     {
     426             :                         // proxy ptr not registered for another interface:
     427             :                         // remove from ptr map
     428             : #if OSL_DEBUG_LEVEL > 0
     429             :                         ::std::size_t erased =
     430             : #endif
     431           0 :                               that->aPtr2ObjectMap.erase( pInterface );
     432             :                         OSL_ASSERT( erased == 1 );
     433             :                     }
     434             : 
     435           0 :                     guard.clear();
     436             : 
     437           0 :                     typelib_typedescription_release( pTypeDescr );
     438           0 :                     (*fpFreeProxy)( pEnv, pInterface );
     439             :                 }
     440             :             }
     441             :         }
     442           0 :     }
     443           0 : }
     444             : 
     445           0 : static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface)
     446             : {
     447           0 :     uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface);
     448           0 : }
     449             : 
     450             : 
     451           0 : static void SAL_CALL defenv_getObjectIdentifier(
     452             :     uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
     453             : {
     454             :     OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
     455           0 :     if (*ppOId)
     456             :     {
     457           0 :         ::rtl_uString_release( *ppOId );
     458           0 :         *ppOId = 0;
     459             :     }
     460             : 
     461             :     uno_DefaultEnvironment * that =
     462           0 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     463           0 :     ::osl::ClearableMutexGuard guard( that->mutex );
     464             : 
     465             :     Ptr2ObjectMap::const_iterator const iFind(
     466           0 :         that->aPtr2ObjectMap.find( pInterface ) );
     467           0 :     if (iFind == that->aPtr2ObjectMap.end())
     468             :     {
     469           0 :         guard.clear();
     470           0 :         (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface );
     471             :     }
     472             :     else
     473             :     {
     474           0 :         rtl_uString * hstr = iFind->second->oid.pData;
     475           0 :         rtl_uString_acquire( hstr );
     476           0 :         *ppOId = hstr;
     477           0 :     }
     478           0 : }
     479             : 
     480             : 
     481           0 : static void SAL_CALL defenv_getRegisteredInterface(
     482             :     uno_ExtEnvironment * pEnv, void ** ppInterface,
     483             :     rtl_uString * pOId, typelib_InterfaceTypeDescription * pTypeDescr )
     484             : {
     485             :     OSL_ENSURE( pEnv && ppInterface && pOId && pTypeDescr, "### null ptr!" );
     486           0 :     if (*ppInterface)
     487             :     {
     488           0 :         (*pEnv->releaseInterface)( pEnv, *ppInterface );
     489           0 :         *ppInterface = 0;
     490             :     }
     491             : 
     492           0 :     OUString const & rOId = OUString::unacquired( &pOId );
     493             :     uno_DefaultEnvironment * that =
     494           0 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     495           0 :     ::osl::MutexGuard guard( that->mutex );
     496             : 
     497             :     OId2ObjectMap::const_iterator const iFind
     498           0 :         ( that->aOId2ObjectMap.find( rOId ) );
     499           0 :     if (iFind != that->aOId2ObjectMap.end())
     500             :     {
     501           0 :         InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr );
     502           0 :         if (pIEntry)
     503             :         {
     504           0 :             (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface );
     505           0 :             *ppInterface = pIEntry->pInterface;
     506             :         }
     507           0 :     }
     508           0 : }
     509             : 
     510             : 
     511           0 : static void SAL_CALL defenv_getRegisteredInterfaces(
     512             :     uno_ExtEnvironment * pEnv, void *** pppInterfaces, sal_Int32 * pnLen,
     513             :     uno_memAlloc memAlloc )
     514             : {
     515             :     OSL_ENSURE( pEnv && pppInterfaces && pnLen && memAlloc, "### null ptr!" );
     516             :     uno_DefaultEnvironment * that =
     517           0 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     518           0 :     ::osl::MutexGuard guard( that->mutex );
     519             : 
     520           0 :     sal_Int32 nLen = that->aPtr2ObjectMap.size();
     521           0 :     sal_Int32 nPos = 0;
     522           0 :     void ** ppInterfaces = (void **) (*memAlloc)( nLen * sizeof (void *) );
     523             : 
     524           0 :     Ptr2ObjectMap::const_iterator iPos( that->aPtr2ObjectMap.begin() );
     525           0 :     Ptr2ObjectMap::const_iterator const iEnd( that->aPtr2ObjectMap.end() );
     526           0 :     while (iPos != iEnd)
     527             :     {
     528           0 :         (*pEnv->acquireInterface)( pEnv, ppInterfaces[nPos++] = (*iPos).first );
     529           0 :         ++iPos;
     530             :     }
     531             : 
     532           0 :     *pppInterfaces = ppInterfaces;
     533           0 :     *pnLen = nLen;
     534           0 : }
     535             : 
     536             : 
     537          48 : static void SAL_CALL defenv_acquire( uno_Environment * pEnv )
     538             : {
     539          48 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     540          48 :     osl_atomic_increment( &that->nWeakRef );
     541          48 :     osl_atomic_increment( &that->nRef );
     542          48 : }
     543             : 
     544             : 
     545          63 : static void SAL_CALL defenv_release( uno_Environment * pEnv )
     546             : {
     547          63 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     548          63 :     if (! osl_atomic_decrement( &that->nRef ))
     549             :     {
     550             :         // invoke dispose callback
     551           2 :         if (pEnv->environmentDisposing)
     552             :         {
     553           2 :             (*pEnv->environmentDisposing)( pEnv );
     554             :         }
     555             : 
     556             :         OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" );
     557             :     }
     558             :     // free memory if no weak refs left
     559          63 :     if (! osl_atomic_decrement( &that->nWeakRef ))
     560             :     {
     561           0 :         delete that;
     562             :     }
     563          63 : }
     564             : 
     565             : 
     566           3 : static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv )
     567             : {
     568           3 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     569           3 :     osl_atomic_increment( &that->nWeakRef );
     570           3 : }
     571             : 
     572             : 
     573           3 : static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv )
     574             : {
     575           3 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     576           3 :     if (! osl_atomic_decrement( &that->nWeakRef ))
     577             :     {
     578           2 :         delete that;
     579             :     }
     580           3 : }
     581             : 
     582             : 
     583          21 : static void SAL_CALL defenv_harden(
     584             :     uno_Environment ** ppHardEnv, uno_Environment * pEnv )
     585             : {
     586          21 :     if (*ppHardEnv)
     587             :     {
     588           0 :         (*(*ppHardEnv)->release)( *ppHardEnv );
     589           0 :         *ppHardEnv = 0;
     590             :     }
     591             : 
     592          21 :     EnvironmentsData & rData = theEnvironmentsData::get();
     593             : 
     594          21 :     if (rData.isDisposing)
     595           1 :         return;
     596             : 
     597          20 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     598             :     {
     599          20 :     ::osl::MutexGuard guard( rData.mutex );
     600          20 :     if (1 == osl_atomic_increment( &that->nRef )) // is dead
     601             :     {
     602           4 :         that->nRef = 0;
     603           4 :         return;
     604          16 :     }
     605             :     }
     606          16 :     osl_atomic_increment( &that->nWeakRef );
     607          16 :     *ppHardEnv = pEnv;
     608             : }
     609             : 
     610             : 
     611           0 : static void SAL_CALL defenv_dispose( SAL_UNUSED_PARAMETER uno_Environment * )
     612             : {
     613           0 : }
     614             : }
     615             : 
     616             : 
     617           3 : uno_DefaultEnvironment::uno_DefaultEnvironment(
     618             :     const OUString & rEnvDcp_, void * pContext_ )
     619             :     : nRef( 0 ),
     620           3 :       nWeakRef( 0 )
     621             : {
     622           3 :     uno_Environment * that = reinterpret_cast< uno_Environment * >(this);
     623           3 :     that->pReserved = 0;
     624             :     // functions
     625           3 :     that->acquire = defenv_acquire;
     626           3 :     that->release = defenv_release;
     627           3 :     that->acquireWeak = defenv_acquireWeak;
     628           3 :     that->releaseWeak = defenv_releaseWeak;
     629           3 :     that->harden = defenv_harden;
     630           3 :     that->dispose = defenv_dispose;
     631           3 :     that->pExtEnv = this;
     632             :     // identifier
     633           3 :     ::rtl_uString_acquire( rEnvDcp_.pData );
     634           3 :     that->pTypeName = rEnvDcp_.pData;
     635           3 :     that->pContext = pContext_;
     636             : 
     637             :     // will be late initialized
     638           3 :     that->environmentDisposing = 0;
     639             : 
     640           3 :     uno_ExtEnvironment::registerInterface = defenv_registerInterface;
     641           3 :     uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface;
     642           3 :     uno_ExtEnvironment::revokeInterface = defenv_revokeInterface;
     643           3 :     uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier;
     644           3 :     uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface;
     645             :     uno_ExtEnvironment::getRegisteredInterfaces =
     646           3 :         defenv_getRegisteredInterfaces;
     647             : 
     648           3 : }
     649             : 
     650             : 
     651           4 : uno_DefaultEnvironment::~uno_DefaultEnvironment()
     652             : {
     653           2 :     ::rtl_uString_release( ((uno_Environment *) this)->pTypeName );
     654           2 : }
     655             : 
     656             : 
     657           0 : static void writeLine(
     658             :     void * stream, const sal_Char * pLine, const sal_Char * pFilter )
     659             : {
     660           0 :     if (pFilter && *pFilter)
     661             :     {
     662             :         // lookup pFilter in pLine
     663           0 :         while (*pLine)
     664             :         {
     665           0 :             if (*pLine == *pFilter)
     666             :             {
     667           0 :                 sal_Int32 nPos = 1;
     668           0 :                 while (pLine[nPos] && pFilter[nPos] == pLine[nPos])
     669             :                 {
     670           0 :                     ++nPos;
     671             :                 }
     672           0 :                 if (! pFilter[nPos])
     673             :                 {
     674           0 :                     if (stream)
     675             :                     {
     676           0 :                         fprintf( (FILE *) stream, "%s\n", pLine );
     677             :                     }
     678             :                     else
     679             :                     {
     680             :                         OSL_TRACE( "%s", pLine );
     681             :                     }
     682             :                 }
     683             :             }
     684           0 :             ++pLine;
     685           0 :         }
     686             :     }
     687             :     else
     688             :     {
     689           0 :         if (stream)
     690             :         {
     691           0 :             fprintf( (FILE *) stream, "%s\n", pLine );
     692             :         }
     693             :         else
     694             :         {
     695           0 :             fprintf( stderr, "%s\n", pLine );
     696             :         }
     697             :     }
     698           0 : }
     699             : 
     700             : 
     701           0 : static void writeLine(
     702             :     void * stream, const OUString & rLine, const sal_Char * pFilter )
     703             : {
     704             :     ::rtl::OString aLine( ::rtl::OUStringToOString(
     705           0 :                               rLine, RTL_TEXTENCODING_ASCII_US ) );
     706           0 :     writeLine( stream, aLine.getStr(), pFilter );
     707           0 : }
     708             : 
     709             : 
     710           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL uno_dumpEnvironment(
     711             :     void * stream, uno_Environment * pEnv, const sal_Char * pFilter )
     712             :     SAL_THROW_EXTERN_C()
     713             : {
     714             :     OSL_ENSURE( pEnv, "### null ptr!" );
     715           0 :     ::rtl::OUStringBuffer buf;
     716             : 
     717           0 :     if (! pEnv->pExtEnv)
     718             :     {
     719             :         writeLine( stream, "###################################"
     720           0 :                    "###########################################", pFilter );
     721           0 :         buf.append( "environment: " );
     722           0 :         buf.append( pEnv->pTypeName );
     723           0 :         writeLine( stream, buf.makeStringAndClear(), pFilter );
     724           0 :         writeLine( stream, "NO INTERFACE INFORMATION AVAILABLE!", pFilter );
     725           0 :         return;
     726             :     }
     727             : 
     728             :     writeLine( stream, "########################################"
     729           0 :                "######################################", pFilter );
     730           0 :     buf.append( "environment dump: " );
     731           0 :     buf.append( pEnv->pTypeName );
     732           0 :     writeLine( stream, buf.makeStringAndClear(), pFilter );
     733             : 
     734             :     uno_DefaultEnvironment * that =
     735           0 :         reinterpret_cast< uno_DefaultEnvironment * >(pEnv);
     736           0 :     ::osl::MutexGuard guard( that->mutex );
     737             : 
     738           0 :     Ptr2ObjectMap ptr2obj( that->aPtr2ObjectMap );
     739           0 :     OId2ObjectMap::const_iterator iPos( that->aOId2ObjectMap.begin() );
     740           0 :     while (iPos != that->aOId2ObjectMap.end())
     741             :     {
     742           0 :         ObjectEntry * pOEntry = iPos->second;
     743             : 
     744           0 :         buf.append( "+ " );
     745           0 :         if (pOEntry->mixedObject)
     746           0 :             buf.append( "mixed " );
     747           0 :         buf.append( "object entry: nRef=" );
     748           0 :         buf.append( pOEntry->nRef, 10 );
     749           0 :         buf.append( "; oid=\"" );
     750           0 :         buf.append( pOEntry->oid );
     751           0 :         buf.append( '\"' );
     752           0 :         writeLine( stream, buf.makeStringAndClear(), pFilter );
     753             : 
     754           0 :         for ( ::std::size_t nPos = 0;
     755           0 :               nPos < pOEntry->aInterfaces.size(); ++nPos )
     756             :         {
     757           0 :             const InterfaceEntry & rIEntry = pOEntry->aInterfaces[nPos];
     758             : 
     759           0 :             buf.append( "  - " );
     760             :             buf.append(
     761           0 :                 ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName );
     762           0 :             if (rIEntry.fpFreeProxy)
     763             :             {
     764           0 :                 buf.append( "; proxy free=0x" );
     765             :                 buf.append(
     766           0 :                     reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 );
     767             :             }
     768             :             else
     769             :             {
     770           0 :                 buf.append( "; original" );
     771             :             }
     772           0 :             buf.append( "; ptr=0x" );
     773             :             buf.append(
     774           0 :                 reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 );
     775             : 
     776           0 :             if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0)
     777             :             {
     778           0 :                 ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface );
     779           0 :                 if (erased != 1)
     780             :                 {
     781           0 :                     buf.append( " (ptr not found in map!)" );
     782             :                 }
     783             :             }
     784           0 :             writeLine( stream, buf.makeStringAndClear(), pFilter );
     785             :         }
     786           0 :         ++iPos;
     787             :     }
     788           0 :     if (! ptr2obj.empty())
     789           0 :         writeLine( stream, "ptr map inconsistency!!!", pFilter );
     790             :     writeLine( stream, "#####################################"
     791           0 :                "#########################################", pFilter );
     792             : }
     793             : 
     794             : 
     795           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL uno_dumpEnvironmentByName(
     796             :     void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter )
     797             :     SAL_THROW_EXTERN_C()
     798             : {
     799           0 :     uno_Environment * pEnv = 0;
     800           0 :     uno_getEnvironment( &pEnv, pEnvDcp, 0 );
     801           0 :     if (pEnv)
     802             :     {
     803           0 :         ::uno_dumpEnvironment( stream, pEnv, pFilter );
     804           0 :         (*pEnv->release)( pEnv );
     805             :     }
     806             :     else
     807             :     {
     808           0 :         ::rtl::OUStringBuffer buf( 32 );
     809           0 :         buf.append( "environment \"" );
     810           0 :         buf.append( pEnvDcp );
     811           0 :         buf.append( "\" does not exist!" );
     812           0 :         writeLine( stream, buf.makeStringAndClear(), pFilter );
     813             :     }
     814           0 : }
     815             : 
     816             : namespace
     817             : {
     818           0 :     class makeOIdPart
     819             :     {
     820             :     private:
     821             :         OUString m_sOidPart;
     822             :     public:
     823           0 :         makeOIdPart()
     824           0 :         {
     825           0 :             ::rtl::OUStringBuffer aRet( 64 );
     826           0 :             aRet.append( "];" );
     827             :             // pid
     828             :             oslProcessInfo info;
     829           0 :             info.Size = sizeof(oslProcessInfo);
     830           0 :             if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) ==
     831             :                 osl_Process_E_None)
     832             :             {
     833           0 :                 aRet.append( (sal_Int64)info.Ident, 16 );
     834             :             }
     835             :             else
     836             :             {
     837           0 :                 aRet.append( "unknown process id" );
     838             :             }
     839             :             // good guid
     840             :             sal_uInt8 ar[16];
     841           0 :             ::rtl_getGlobalProcessId( ar );
     842           0 :             aRet.append( ';' );
     843           0 :             for ( sal_Int32 i = 0; i < 16; ++i )
     844           0 :                 aRet.append( (sal_Int32)ar[i], 16 );
     845             : 
     846           0 :             m_sOidPart = aRet.makeStringAndClear();
     847           0 :         }
     848           0 :         const OUString& getOIdPart() const { return m_sOidPart; }
     849             :     };
     850             : 
     851             :     class theStaticOIdPart : public rtl::Static<makeOIdPart, theStaticOIdPart> {};
     852             : }
     853             : 
     854             : 
     855           0 : inline static const OUString & unoenv_getStaticOIdPart()
     856             : {
     857           0 :     return theStaticOIdPart::get().getOIdPart();
     858             : }
     859             : 
     860             : extern "C"
     861             : {
     862             : 
     863             : 
     864           0 : static void SAL_CALL unoenv_computeObjectIdentifier(
     865             :     uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
     866             : {
     867             :     OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
     868           0 :     if (*ppOId)
     869             :     {
     870           0 :         ::rtl_uString_release( *ppOId );
     871           0 :         *ppOId = 0;
     872             :     }
     873             : 
     874             :     uno_Interface * pUnoI = (uno_Interface *)
     875             :         ::cppu::binuno_queryInterface(
     876             :             pInterface, *typelib_static_type_getByTypeClass(
     877           0 :                 typelib_TypeClass_INTERFACE ) );
     878           0 :     if (0 != pUnoI)
     879             :     {
     880           0 :         (*pUnoI->release)( pUnoI );
     881             :         // interface
     882           0 :         ::rtl::OUStringBuffer oid( 64 );
     883           0 :         oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 );
     884           0 :         oid.append( ';' );
     885             :         // environment[context]
     886           0 :         oid.append( ((uno_Environment *) pEnv)->pTypeName );
     887           0 :         oid.append( '[' );
     888             :         oid.append( reinterpret_cast< sal_Int64 >(
     889             :                         reinterpret_cast<
     890           0 :                         uno_Environment * >(pEnv)->pContext ), 16 );
     891             :         // process;good guid
     892           0 :         oid.append( unoenv_getStaticOIdPart() );
     893           0 :         OUString aStr( oid.makeStringAndClear() );
     894           0 :         ::rtl_uString_acquire( *ppOId = aStr.pData );
     895             :     }
     896           0 : }
     897             : 
     898             : 
     899           0 : static void SAL_CALL unoenv_acquireInterface(
     900             :     SAL_UNUSED_PARAMETER uno_ExtEnvironment *, void * pUnoI_ )
     901             : {
     902           0 :     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
     903           0 :     (*pUnoI->acquire)( pUnoI );
     904           0 : }
     905             : 
     906             : 
     907           0 : static void SAL_CALL unoenv_releaseInterface(
     908             :     SAL_UNUSED_PARAMETER uno_ExtEnvironment *, void * pUnoI_ )
     909             : {
     910           0 :     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
     911           0 :     (*pUnoI->release)( pUnoI );
     912           0 : }
     913             : }
     914             : 
     915             : 
     916           2 : EnvironmentsData::~EnvironmentsData()
     917             : {
     918           1 :     ::osl::MutexGuard guard( mutex );
     919           1 :     isDisposing = true;
     920             : 
     921           6 :     for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
     922           4 :           iPos != aName2EnvMap.end(); ++iPos )
     923             :     {
     924           1 :         uno_Environment * pWeak = iPos->second;
     925           1 :         uno_Environment * pHard = 0;
     926           1 :         (*pWeak->harden)( &pHard, pWeak );
     927           1 :         (*pWeak->releaseWeak)( pWeak );
     928             : 
     929           1 :         if (pHard)
     930             :         {
     931             : #if OSL_DEBUG_LEVEL > 1
     932             :             ::uno_dumpEnvironment( 0, pHard, 0 );
     933             : #endif
     934           0 :             (*pHard->dispose)( pHard ); // send explicit dispose
     935           0 :             (*pHard->release)( pHard );
     936             :         }
     937           1 :     }
     938           1 : }
     939             : 
     940             : 
     941          19 : inline void EnvironmentsData::getEnvironment(
     942             :     uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext )
     943             : {
     944          19 :     if (*ppEnv)
     945             :     {
     946           0 :         (*(*ppEnv)->release)( *ppEnv );
     947           0 :         *ppEnv = 0;
     948             :     }
     949             : 
     950             :     OUString aKey(
     951          19 :         OUString::number( reinterpret_cast< sal_IntPtr >(pContext) ) );
     952          19 :     aKey += rEnvDcp;
     953             : 
     954             :     // try to find registered mapping
     955             :     OUString2EnvironmentMap::const_iterator const iFind(
     956          19 :         aName2EnvMap.find( aKey ) );
     957          19 :     if (iFind != aName2EnvMap.end())
     958             :     {
     959          18 :         uno_Environment * pWeak = iFind->second;
     960          18 :         (*pWeak->harden)( ppEnv, pWeak );
     961          19 :     }
     962          19 : }
     963             : 
     964             : 
     965           3 : inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv )
     966             : {
     967             :     OSL_ENSURE( ppEnv, "### null ptr!" );
     968           3 :     uno_Environment * pEnv =  *ppEnv;
     969             : 
     970             :     OUString aKey(
     971           3 :         OUString::number( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) );
     972           3 :     aKey += pEnv->pTypeName;
     973             : 
     974             :     // try to find registered environment
     975             :     OUString2EnvironmentMap::const_iterator const iFind(
     976           3 :         aName2EnvMap.find( aKey ) );
     977           3 :     if (iFind == aName2EnvMap.end())
     978             :     {
     979           1 :         (*pEnv->acquireWeak)( pEnv );
     980             :         ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion (
     981             :             aName2EnvMap.insert(
     982           1 :                 OUString2EnvironmentMap::value_type( aKey, pEnv ) ) );
     983             :         SAL_WARN_IF( !insertion.second, "cppu", "key " << aKey << " already in env map" );
     984             :     }
     985             :     else
     986             :     {
     987           2 :         uno_Environment * pHard = 0;
     988           2 :         uno_Environment * pWeak = iFind->second;
     989           2 :         (*pWeak->harden)( &pHard, pWeak );
     990           2 :         if (pHard)
     991             :         {
     992           0 :             (*pEnv->release)( pEnv );
     993           0 :             *ppEnv = pHard;
     994             :         }
     995             :         else // registered one is dead
     996             :         {
     997           2 :             (*pWeak->releaseWeak)( pWeak );
     998           2 :             (*pEnv->acquireWeak)( pEnv );
     999           2 :             aName2EnvMap[ aKey ] = pEnv;
    1000             :         }
    1001           3 :     }
    1002           3 : }
    1003             : 
    1004             : 
    1005           0 : inline void EnvironmentsData::getRegisteredEnvironments(
    1006             :     uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
    1007             :     const OUString & rEnvDcp )
    1008             : {
    1009             :     OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" );
    1010             : 
    1011             :     // max size
    1012           0 :     uno_Environment ** ppFound = (uno_Environment **)alloca(
    1013             :         sizeof(uno_Environment *) * aName2EnvMap.size() );
    1014           0 :     sal_Int32 nSize = 0;
    1015             : 
    1016             :     // find matching environment
    1017           0 :     for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
    1018           0 :           iPos != aName2EnvMap.end(); ++iPos )
    1019             :     {
    1020           0 :         uno_Environment * pWeak = iPos->second;
    1021           0 :         if (rEnvDcp.isEmpty() ||
    1022           0 :             rEnvDcp.equals( pWeak->pTypeName ))
    1023             :         {
    1024           0 :             ppFound[nSize] = 0;
    1025           0 :             (*pWeak->harden)( &ppFound[nSize], pWeak );
    1026           0 :             if (ppFound[nSize])
    1027           0 :                 ++nSize;
    1028             :         }
    1029             :     }
    1030             : 
    1031           0 :     *pnLen = nSize;
    1032           0 :     if (nSize)
    1033             :     {
    1034             :         *pppEnvs = (uno_Environment **) (*memAlloc)(
    1035           0 :             sizeof (uno_Environment *) * nSize );
    1036             :         OSL_ASSERT( *pppEnvs );
    1037           0 :         while (nSize--)
    1038             :         {
    1039           0 :             (*pppEnvs)[nSize] = ppFound[nSize];
    1040             :         }
    1041             :     }
    1042             :     else
    1043             :     {
    1044           0 :         *pppEnvs = 0;
    1045             :     }
    1046           0 : }
    1047             : 
    1048           3 : static bool loadEnv(OUString const  & cLibStem,
    1049             :                     uno_Environment * pEnv)
    1050             : {
    1051             : #ifdef DISABLE_DYNLOADING
    1052             :     uno_initEnvironmentFunc fpInit;
    1053             : 
    1054             :     if ( cLibStem == CPPU_CURRENT_LANGUAGE_BINDING_NAME "_uno" )
    1055             :         fpInit = CPPU_ENV_uno_initEnvironment;
    1056             : #if HAVE_FEATURE_JAVA
    1057             :     else if ( cLibStem == "java_uno" )
    1058             :         fpInit = java_uno_initEnvironment;
    1059             : #endif
    1060             :     else
    1061             :     {
    1062             : #if OSL_DEBUG_LEVEL > 1
    1063             :         OSL_TRACE( "%s: Unhandled env: %s", __PRETTY_FUNCTION__, OUStringToOString( cLibStem, RTL_TEXTENCODING_ASCII_US).getStr() );
    1064             : #endif
    1065             :         return false;
    1066             :     }
    1067             : #else
    1068             :     // late init with some code from matching uno language binding
    1069             :     // will be unloaded by environment
    1070           3 :     oslModule hMod = cppu::detail::loadModule( cLibStem );
    1071             : 
    1072           3 :     if (!hMod)
    1073           0 :         return false;
    1074             : 
    1075           3 :     OUString aSymbolName(UNO_INIT_ENVIRONMENT);
    1076             :     uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc)
    1077           3 :         ::osl_getFunctionSymbol( hMod, aSymbolName.pData );
    1078             : 
    1079           3 :     if (!fpInit)
    1080             :     {
    1081           0 :         ::osl_unloadModule( hMod );
    1082           0 :         return false;
    1083             :     }
    1084             : #endif
    1085             : 
    1086           3 :     (*fpInit)( pEnv ); // init of environment
    1087           3 :     return true;
    1088             : }
    1089             : 
    1090             : 
    1091             : extern "C"
    1092             : {
    1093             : 
    1094             : 
    1095           3 : static uno_Environment * initDefaultEnvironment(
    1096             :     const OUString & rEnvDcp, void * pContext )
    1097             : {
    1098           3 :     uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase;
    1099           3 :     (*pEnv->acquire)( pEnv );
    1100             : 
    1101           3 :     OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp);
    1102             : 
    1103             :     // create default environment
    1104           3 :     if ( envTypeName == UNO_LB_UNO )
    1105             :     {
    1106           0 :         uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
    1107           0 :         that->computeObjectIdentifier = unoenv_computeObjectIdentifier;
    1108           0 :         that->acquireInterface = unoenv_acquireInterface;
    1109           0 :         that->releaseInterface = unoenv_releaseInterface;
    1110             : 
    1111           0 :         OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp);
    1112           0 :         if (!envPurpose.isEmpty())
    1113             :         {
    1114           0 :             rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1);
    1115           0 :             libStem += rtl::OUString("_uno_uno");
    1116             : 
    1117           0 :             if(!loadEnv(libStem, pEnv))
    1118             :             {
    1119           0 :                 pEnv->release(pEnv);
    1120           0 :                 return NULL;
    1121           0 :             }
    1122           0 :         }
    1123             :     }
    1124             :     else
    1125             :     {
    1126             :         // late init with some code from matching uno language binding
    1127           3 :         ::rtl::OUStringBuffer aLibName( 16 );
    1128           3 :         aLibName.append( envTypeName );
    1129           3 :         aLibName.append( "_uno" );
    1130           6 :         OUString aStr( aLibName.makeStringAndClear() );
    1131             : 
    1132           3 :         if (!loadEnv(aStr, pEnv))
    1133             :         {
    1134           0 :             pEnv->release(pEnv);
    1135           0 :             return NULL;
    1136           3 :         }
    1137             :     }
    1138             : 
    1139           3 :     return pEnv;
    1140             : }
    1141             : 
    1142             : 
    1143           0 : CPPU_DLLPUBLIC void SAL_CALL uno_createEnvironment(
    1144             :     uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
    1145             :     SAL_THROW_EXTERN_C()
    1146             : {
    1147             :     OSL_ENSURE( ppEnv, "### null ptr!" );
    1148           0 :     if (*ppEnv)
    1149           0 :         (*(*ppEnv)->release)( *ppEnv );
    1150             : 
    1151           0 :     OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
    1152           0 :     *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
    1153           0 : }
    1154             : 
    1155             : 
    1156          19 : CPPU_DLLPUBLIC void SAL_CALL uno_getEnvironment(
    1157             :     uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
    1158             :     SAL_THROW_EXTERN_C()
    1159             : {
    1160             :     OSL_ENSURE( ppEnv, "### null ptr!" );
    1161          19 :     OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
    1162             : 
    1163          19 :     EnvironmentsData & rData = theEnvironmentsData::get();
    1164             : 
    1165          19 :     ::osl::MutexGuard guard( rData.mutex );
    1166          19 :     rData.getEnvironment( ppEnv, rEnvDcp, pContext );
    1167          19 :     if (! *ppEnv)
    1168             :     {
    1169           3 :         *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
    1170           3 :         if (*ppEnv)
    1171             :         {
    1172             :             // register new environment:
    1173           3 :             rData.registerEnvironment( ppEnv );
    1174             :         }
    1175          19 :     }
    1176          19 : }
    1177             : 
    1178             : 
    1179           0 : CPPU_DLLPUBLIC void SAL_CALL uno_getRegisteredEnvironments(
    1180             :     uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
    1181             :     rtl_uString * pEnvDcp )
    1182             :     SAL_THROW_EXTERN_C()
    1183             : {
    1184           0 :     EnvironmentsData & rData = theEnvironmentsData::get();
    1185             : 
    1186           0 :     ::osl::MutexGuard guard( rData.mutex );
    1187             :     rData.getRegisteredEnvironments(
    1188             :         pppEnvs, pnLen, memAlloc,
    1189           0 :         (pEnvDcp ? OUString(pEnvDcp) : OUString()) );
    1190           0 : }
    1191             : 
    1192             : } // extern "C"
    1193             : 
    1194             : }
    1195             : 
    1196             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10