LCOV - code coverage report
Current view: top level - libreoffice/cppu/source/uno - lbenv.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 309 489 63.2 %
Date: 2012-12-27 Functions: 35 44 79.5 %
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             : 
      21             : #include "cppu/EnvDcp.hxx"
      22             : 
      23             : #include "sal/alloca.h"
      24             : #include "sal/log.hxx"
      25             : #include "osl/diagnose.h"
      26             : #include "osl/interlck.h"
      27             : #include "osl/mutex.hxx"
      28             : #include "osl/module.h"
      29             : #include "osl/process.h"
      30             : #include "rtl/process.h"
      31             : #include "rtl/unload.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         853 : inline static bool td_equals( typelib_InterfaceTypeDescription * pTD1,
      56             :                               typelib_InterfaceTypeDescription * pTD2 )
      57             : {
      58             :     return (pTD1 == pTD2 ||
      59             :             (((typelib_TypeDescription *)pTD1)->pTypeName->length ==
      60             :              ((typelib_TypeDescription *)pTD2)->pTypeName->length &&
      61             :              ::rtl_ustr_compare(
      62             :                  ((typelib_TypeDescription *) pTD1)->pTypeName->buffer,
      63         853 :                  ((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        7059 : 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       25162 :     ::std::size_t operator () ( const void * pKey ) const
     101       25162 :         { return (::std::size_t) pKey; }
     102             : };
     103             : 
     104             : //------------------------------------------------------------------------------
     105             : struct FctOUStringHash :
     106             :     public ::std::unary_function< const OUString &, ::std::size_t >
     107             : {
     108       44627 :     ::std::size_t operator () ( const OUString & rKey ) const
     109       44627 :         { 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         257 :     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        7059 : inline ObjectEntry::ObjectEntry( OUString const & rOId_ )
     168             :     : oid( rOId_ ),
     169             :       nRef( 0 ),
     170        7059 :       mixedObject( false )
     171             : {
     172        7059 :     aInterfaces.reserve( 2 );
     173        7059 : }
     174             : 
     175             : //______________________________________________________________________________
     176        7074 : inline void ObjectEntry::append(
     177             :     uno_DefaultEnvironment * pEnv,
     178             :     void * pInterface, typelib_InterfaceTypeDescription * pTypeDescr,
     179             :     uno_freeProxyFunc fpFreeProxy )
     180             : {
     181             :     InterfaceEntry aNewEntry;
     182        7074 :     if (! fpFreeProxy)
     183        3520 :         (*pEnv->acquireInterface)( pEnv, pInterface );
     184        7074 :     aNewEntry.refCount = 1;
     185        7074 :     aNewEntry.pInterface = pInterface;
     186        7074 :     aNewEntry.fpFreeProxy = fpFreeProxy;
     187        7074 :     typelib_typedescription_acquire( (typelib_TypeDescription *) pTypeDescr );
     188        7074 :     aNewEntry.pTypeDescr = pTypeDescr;
     189             : 
     190             :     ::std::pair< Ptr2ObjectMap::iterator, bool > i(
     191             :         pEnv->aPtr2ObjectMap.insert( Ptr2ObjectMap::value_type(
     192        7074 :                                          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        7074 :     aInterfaces.push_back( aNewEntry );
     199        7074 : }
     200             : 
     201             : //______________________________________________________________________________
     202        2224 : inline InterfaceEntry * ObjectEntry::find(
     203             :     typelib_InterfaceTypeDescription * pTypeDescr_ )
     204             : {
     205             :     OSL_ASSERT( ! aInterfaces.empty() );
     206        2224 :     if (aInterfaces.empty())
     207           0 :         return 0;
     208             : 
     209             :     // shortcut common case:
     210             :     OUString const & type_name =
     211             :         OUString::unacquired(
     212        2224 :             &((typelib_TypeDescription *) pTypeDescr_)->pTypeName );
     213        2224 :     if ( type_name == "com.sun.star.uno.XInterface" )
     214             :     {
     215        1980 :         return &aInterfaces[ 0 ];
     216             :     }
     217             : 
     218         244 :     ::std::size_t nSize = aInterfaces.size();
     219         398 :     for ( ::std::size_t nPos = 0; nPos < nSize; ++nPos )
     220             :     {
     221             :         typelib_InterfaceTypeDescription * pITD =
     222         365 :             aInterfaces[ nPos ].pTypeDescr;
     223        1372 :         while (pITD)
     224             :         {
     225         853 :             if (td_equals( pITD, pTypeDescr_ ))
     226         211 :                 return &aInterfaces[ nPos ];
     227         642 :             pITD = pITD->pBaseTypeDescription;
     228             :         }
     229             :     }
     230          33 :     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        3554 : 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        3554 :     OUString const & rOId = OUString::unacquired( &pOId );
     256             : 
     257             :     uno_DefaultEnvironment * that =
     258        3554 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     259        3554 :     ::osl::ClearableMutexGuard guard( that->mutex );
     260             : 
     261             :     // try to insert dummy 0:
     262             :     std::pair<OId2ObjectMap::iterator, bool> const insertion(
     263        3554 :         that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) );
     264        3554 :     if (insertion.second)
     265             :     {
     266        3515 :         ObjectEntry * pOEntry = new ObjectEntry( rOId );
     267        3515 :         insertion.first->second = pOEntry;
     268        3515 :         ++pOEntry->nRef; // another register call on object
     269        3515 :         pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
     270             :     }
     271             :     else // object entry exists
     272             :     {
     273          39 :         ObjectEntry * pOEntry = insertion.first->second;
     274          39 :         ++pOEntry->nRef; // another register call on object
     275          39 :         InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
     276             : 
     277          39 :         if (pIEntry) // type entry exists
     278             :         {
     279          34 :             ++pIEntry->refCount;
     280          34 :             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           5 :             pOEntry->append( that, *ppInterface, pTypeDescr, 0 );
     292             :         }
     293        3554 :     }
     294        3554 : }
     295             : 
     296             : //------------------------------------------------------------------------------
     297        3584 : 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        3584 :     OUString const & rOId = OUString::unacquired( &pOId );
     304             : 
     305             :     uno_DefaultEnvironment * that =
     306        3584 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     307        3584 :     ::osl::ClearableMutexGuard guard( that->mutex );
     308             : 
     309             :     // try to insert dummy 0:
     310             :     std::pair<OId2ObjectMap::iterator, bool> const insertion(
     311        3584 :         that->aOId2ObjectMap.insert( OId2ObjectMap::value_type( rOId, (ObjectEntry*)0 ) ) );
     312        3584 :     if (insertion.second)
     313             :     {
     314        3544 :         ObjectEntry * pOEntry = new ObjectEntry( rOId );
     315        3544 :         insertion.first->second = pOEntry;
     316        3544 :         ++pOEntry->nRef; // another register call on object
     317        3544 :         pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
     318             :     }
     319             :     else // object entry exists
     320             :     {
     321          40 :         ObjectEntry * pOEntry = insertion.first->second;
     322             : 
     323             :         // first registration was an original, then registerProxyInterface():
     324             :         pOEntry->mixedObject |=
     325          40 :             (!pOEntry->aInterfaces.empty() &&
     326          40 :              pOEntry->aInterfaces[ 0 ].fpFreeProxy == 0);
     327             : 
     328          40 :         ++pOEntry->nRef; // another register call on object
     329          40 :         InterfaceEntry * pIEntry = pOEntry->find( pTypeDescr );
     330             : 
     331          40 :         if (pIEntry) // type entry exists
     332             :         {
     333          30 :             if (pIEntry->pInterface == *ppInterface)
     334             :             {
     335          30 :                 ++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          10 :             pOEntry->append( that, *ppInterface, pTypeDescr, freeProxy );
     350             :         }
     351        3584 :     }
     352        3584 : }
     353             : 
     354             : //------------------------------------------------------------------------------
     355        7138 : static void SAL_CALL s_stub_defenv_revokeInterface(va_list * pParam)
     356             : {
     357        7138 :     uno_ExtEnvironment * pEnv       = va_arg(*pParam, uno_ExtEnvironment *);
     358        7138 :     void               * pInterface = va_arg(*pParam, void *);
     359             : 
     360             :     OSL_ENSURE( pEnv && pInterface, "### null ptr!" );
     361             :     uno_DefaultEnvironment * that =
     362        7138 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     363        7138 :     ::osl::ClearableMutexGuard guard( that->mutex );
     364             : 
     365             :     Ptr2ObjectMap::const_iterator const iFind(
     366        7138 :         that->aPtr2ObjectMap.find( pInterface ) );
     367             :     OSL_ASSERT( iFind != that->aPtr2ObjectMap.end() );
     368        7138 :     ObjectEntry * pOEntry = iFind->second;
     369        7138 :     if (! --pOEntry->nRef)
     370             :     {
     371             :         // cleanup maps
     372        7059 :         that->aOId2ObjectMap.erase( pOEntry->oid );
     373             :         sal_Int32 nPos;
     374       21192 :         for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
     375             :         {
     376        7074 :             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        7059 :         guard.clear();
     382             : 
     383             :         // release interfaces
     384       21192 :         for ( nPos = pOEntry->aInterfaces.size(); nPos--; )
     385             :         {
     386        7074 :             InterfaceEntry const & rEntry = pOEntry->aInterfaces[nPos];
     387             :             typelib_typedescription_release(
     388        7074 :                 (typelib_TypeDescription *) rEntry.pTypeDescr );
     389        7074 :             if (rEntry.fpFreeProxy) // is proxy or used interface?
     390             :             {
     391        3554 :                 (*rEntry.fpFreeProxy)( pEnv, rEntry.pInterface );
     392             :             }
     393             :             else
     394             :             {
     395        3520 :                 (*pEnv->releaseInterface)( pEnv, rEntry.pInterface );
     396             :             }
     397             :         }
     398             : 
     399        7059 :         delete pOEntry;
     400             :     }
     401          79 :     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        7138 :     }
     443        7138 : }
     444             : 
     445        7138 : static void SAL_CALL defenv_revokeInterface(uno_ExtEnvironment * pEnv, void * pInterface)
     446             : {
     447        7138 :     uno_Environment_invoke(&pEnv->aBase, s_stub_defenv_revokeInterface, pEnv, pInterface);
     448        7138 : }
     449             : 
     450             : //------------------------------------------------------------------------------
     451        5631 : 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        5631 :     if (*ppOId)
     456             :     {
     457           0 :         ::rtl_uString_release( *ppOId );
     458           0 :         *ppOId = 0;
     459             :     }
     460             : 
     461             :     uno_DefaultEnvironment * that =
     462        5631 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     463        5631 :     ::osl::ClearableMutexGuard guard( that->mutex );
     464             : 
     465             :     Ptr2ObjectMap::const_iterator const iFind(
     466        5631 :         that->aPtr2ObjectMap.find( pInterface ) );
     467        5631 :     if (iFind == that->aPtr2ObjectMap.end())
     468             :     {
     469        3519 :         guard.clear();
     470        3519 :         (*pEnv->computeObjectIdentifier)( pEnv, ppOId, pInterface );
     471             :     }
     472             :     else
     473             :     {
     474        2112 :         rtl_uString * hstr = iFind->second->oid.pData;
     475        2112 :         rtl_uString_acquire( hstr );
     476        2112 :         *ppOId = hstr;
     477        5631 :     }
     478        5631 : }
     479             : 
     480             : //------------------------------------------------------------------------------
     481        5689 : 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        5689 :     if (*ppInterface)
     487             :     {
     488           0 :         (*pEnv->releaseInterface)( pEnv, *ppInterface );
     489           0 :         *ppInterface = 0;
     490             :     }
     491             : 
     492        5689 :     OUString const & rOId = OUString::unacquired( &pOId );
     493             :     uno_DefaultEnvironment * that =
     494        5689 :         static_cast< uno_DefaultEnvironment * >( pEnv );
     495        5689 :     ::osl::MutexGuard guard( that->mutex );
     496             : 
     497             :     OId2ObjectMap::const_iterator const iFind
     498        5689 :         ( that->aOId2ObjectMap.find( rOId ) );
     499        5689 :     if (iFind != that->aOId2ObjectMap.end())
     500             :     {
     501        2145 :         InterfaceEntry const * pIEntry = iFind->second->find( pTypeDescr );
     502        2145 :         if (pIEntry)
     503             :         {
     504        2127 :             (*pEnv->acquireInterface)( pEnv, pIEntry->pInterface );
     505        2127 :             *ppInterface = pIEntry->pInterface;
     506             :         }
     507        5689 :     }
     508        5689 : }
     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       72033 : static void SAL_CALL defenv_acquire( uno_Environment * pEnv )
     538             : {
     539       72033 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     540       72033 :     osl_atomic_increment( &that->nWeakRef );
     541       72033 :     osl_atomic_increment( &that->nRef );
     542       72033 : }
     543             : 
     544             : //------------------------------------------------------------------------------
     545       80493 : static void SAL_CALL defenv_release( uno_Environment * pEnv )
     546             : {
     547       80493 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     548       80493 :     if (! osl_atomic_decrement( &that->nRef ))
     549             :     {
     550             :         // invoke dispose callback
     551        6144 :         if (pEnv->environmentDisposing)
     552             :         {
     553        4394 :             (*pEnv->environmentDisposing)( pEnv );
     554             :         }
     555             : 
     556             :         OSL_ENSURE( that->aOId2ObjectMap.empty(), "### object entries left!" );
     557             :     }
     558             :     // free memory if no weak refs left
     559       80493 :     if (! osl_atomic_decrement( &that->nWeakRef ))
     560             :     {
     561           2 :         delete that;
     562             :     }
     563       80493 : }
     564             : 
     565             : //------------------------------------------------------------------------------
     566        6173 : static void SAL_CALL defenv_acquireWeak( uno_Environment * pEnv )
     567             : {
     568        6173 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     569        6173 :     osl_atomic_increment( &that->nWeakRef );
     570        6173 : }
     571             : 
     572             : //------------------------------------------------------------------------------
     573        6173 : static void SAL_CALL defenv_releaseWeak( uno_Environment * pEnv )
     574             : {
     575        6173 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     576        6173 :     if (! osl_atomic_decrement( &that->nWeakRef ))
     577             :     {
     578        6142 :         delete that;
     579             :     }
     580        6173 : }
     581             : 
     582             : //------------------------------------------------------------------------------
     583       20562 : static void SAL_CALL defenv_harden(
     584             :     uno_Environment ** ppHardEnv, uno_Environment * pEnv )
     585             : {
     586       20562 :     if (*ppHardEnv)
     587             :     {
     588           0 :         (*(*ppHardEnv)->release)( *ppHardEnv );
     589           0 :         *ppHardEnv = 0;
     590             :     }
     591             : 
     592       20562 :     EnvironmentsData & rData = theEnvironmentsData::get();
     593             : 
     594       20562 :     if (rData.isDisposing)
     595         275 :         return;
     596             : 
     597       20287 :     uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
     598             :     {
     599       20287 :     ::osl::MutexGuard guard( rData.mutex );
     600       20287 :     if (1 == osl_atomic_increment( &that->nRef )) // is dead
     601             :     {
     602       11796 :         that->nRef = 0;
     603             :         return;
     604       20287 :     }
     605             :     }
     606        8491 :     osl_atomic_increment( &that->nWeakRef );
     607        8491 :     *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        6175 : uno_DefaultEnvironment::uno_DefaultEnvironment(
     618             :     const OUString & rEnvDcp_, void * pContext_ )
     619             :     : nRef( 0 ),
     620        6175 :       nWeakRef( 0 )
     621             : {
     622        6175 :     uno_Environment * that = reinterpret_cast< uno_Environment * >(this);
     623        6175 :     that->pReserved = 0;
     624             :     // functions
     625        6175 :     that->acquire = defenv_acquire;
     626        6175 :     that->release = defenv_release;
     627        6175 :     that->acquireWeak = defenv_acquireWeak;
     628        6175 :     that->releaseWeak = defenv_releaseWeak;
     629        6175 :     that->harden = defenv_harden;
     630        6175 :     that->dispose = defenv_dispose;
     631        6175 :     that->pExtEnv = this;
     632             :     // identifier
     633        6175 :     ::rtl_uString_acquire( rEnvDcp_.pData );
     634        6175 :     that->pTypeName = rEnvDcp_.pData;
     635        6175 :     that->pContext = pContext_;
     636             : 
     637             :     // will be late initialized
     638        6175 :     that->environmentDisposing = 0;
     639             : 
     640        6175 :     uno_ExtEnvironment::registerInterface = defenv_registerInterface;
     641        6175 :     uno_ExtEnvironment::registerProxyInterface = defenv_registerProxyInterface;
     642        6175 :     uno_ExtEnvironment::revokeInterface = defenv_revokeInterface;
     643        6175 :     uno_ExtEnvironment::getObjectIdentifier = defenv_getObjectIdentifier;
     644        6175 :     uno_ExtEnvironment::getRegisteredInterface = defenv_getRegisteredInterface;
     645             :     uno_ExtEnvironment::getRegisteredInterfaces =
     646        6175 :         defenv_getRegisteredInterfaces;
     647             : 
     648        6175 : }
     649             : 
     650             : //______________________________________________________________________________
     651       12288 : uno_DefaultEnvironment::~uno_DefaultEnvironment()
     652             : {
     653        6144 :     ::rtl_uString_release( ((uno_Environment *) this)->pTypeName );
     654        6144 : }
     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.appendAscii( RTL_CONSTASCII_STRINGPARAM("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.appendAscii( RTL_CONSTASCII_STRINGPARAM("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.appendAscii( RTL_CONSTASCII_STRINGPARAM("+ ") );
     745           0 :         if (pOEntry->mixedObject)
     746           0 :             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("mixed ") );
     747           0 :         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("object entry: nRef=") );
     748           0 :         buf.append( pOEntry->nRef, 10 );
     749           0 :         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; oid=\"") );
     750           0 :         buf.append( pOEntry->oid );
     751           0 :         buf.append( (sal_Unicode) '\"' );
     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.appendAscii( RTL_CONSTASCII_STRINGPARAM("  - ") );
     760             :             buf.append(
     761           0 :                 ((typelib_TypeDescription *) rIEntry.pTypeDescr)->pTypeName );
     762           0 :             if (rIEntry.fpFreeProxy)
     763             :             {
     764             :                 buf.appendAscii(
     765           0 :                     RTL_CONSTASCII_STRINGPARAM("; proxy free=0x") );
     766             :                 buf.append(
     767           0 :                     reinterpret_cast< sal_IntPtr >(rIEntry.fpFreeProxy), 16 );
     768             :             }
     769             :             else
     770             :             {
     771           0 :                 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; original") );
     772             :             }
     773           0 :             buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("; ptr=0x") );
     774             :             buf.append(
     775           0 :                 reinterpret_cast< sal_IntPtr >(rIEntry.pInterface), 16 );
     776             : 
     777           0 :             if (pOEntry->find( rIEntry.pInterface, nPos + 1 ) < 0)
     778             :             {
     779           0 :                 ::std::size_t erased = ptr2obj.erase( rIEntry.pInterface );
     780           0 :                 if (erased != 1)
     781             :                 {
     782             :                     buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
     783           0 :                                          " (ptr not found in map!)") );
     784             :                 }
     785             :             }
     786           0 :             writeLine( stream, buf.makeStringAndClear(), pFilter );
     787             :         }
     788           0 :         ++iPos;
     789             :     }
     790           0 :     if (! ptr2obj.empty())
     791           0 :         writeLine( stream, "ptr map inconsistency!!!", pFilter );
     792             :     writeLine( stream, "#####################################"
     793           0 :                "#########################################", pFilter );
     794             : }
     795             : 
     796             : //##############################################################################
     797           0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL uno_dumpEnvironmentByName(
     798             :     void * stream, rtl_uString * pEnvDcp, const sal_Char * pFilter )
     799             :     SAL_THROW_EXTERN_C()
     800             : {
     801           0 :     uno_Environment * pEnv = 0;
     802           0 :     uno_getEnvironment( &pEnv, pEnvDcp, 0 );
     803           0 :     if (pEnv)
     804             :     {
     805           0 :         ::uno_dumpEnvironment( stream, pEnv, pFilter );
     806           0 :         (*pEnv->release)( pEnv );
     807             :     }
     808             :     else
     809             :     {
     810           0 :         ::rtl::OUStringBuffer buf( 32 );
     811           0 :         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("environment \"") );
     812           0 :         buf.append( pEnvDcp );
     813           0 :         buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not exist!") );
     814           0 :         writeLine( stream, buf.makeStringAndClear(), pFilter );
     815             :     }
     816           0 : }
     817             : 
     818             : namespace
     819             : {
     820          18 :     class makeOIdPart
     821             :     {
     822             :     private:
     823             :         OUString m_sOidPart;
     824             :     public:
     825          18 :         makeOIdPart()
     826          18 :         {
     827          18 :             ::rtl::OUStringBuffer aRet( 64 );
     828          18 :             aRet.appendAscii( RTL_CONSTASCII_STRINGPARAM("];") );
     829             :             // pid
     830             :             oslProcessInfo info;
     831          18 :             info.Size = sizeof(oslProcessInfo);
     832          18 :             if (::osl_getProcessInfo( 0, osl_Process_IDENTIFIER, &info ) ==
     833             :                 osl_Process_E_None)
     834             :             {
     835          18 :                 aRet.append( (sal_Int64)info.Ident, 16 );
     836             :             }
     837             :             else
     838             :             {
     839             :                 aRet.appendAscii(
     840           0 :                     RTL_CONSTASCII_STRINGPARAM("unknown process id") );
     841             :             }
     842             :             // good guid
     843             :             sal_uInt8 ar[16];
     844          18 :             ::rtl_getGlobalProcessId( ar );
     845          18 :             aRet.append( (sal_Unicode)';' );
     846         306 :             for ( sal_Int32 i = 0; i < 16; ++i )
     847         288 :                 aRet.append( (sal_Int32)ar[i], 16 );
     848             : 
     849          18 :             m_sOidPart = aRet.makeStringAndClear();
     850          18 :         }
     851        1662 :         const OUString& getOIdPart() const { return m_sOidPart; }
     852             :     };
     853             : 
     854             :     class theStaticOIdPart : public rtl::Static<makeOIdPart, theStaticOIdPart> {};
     855             : }
     856             : 
     857             : //------------------------------------------------------------------------------
     858        1662 : inline static const OUString & unoenv_getStaticOIdPart()
     859             : {
     860        1662 :     return theStaticOIdPart::get().getOIdPart();
     861             : }
     862             : 
     863             : extern "C"
     864             : {
     865             : 
     866             : //------------------------------------------------------------------------------
     867        1662 : static void SAL_CALL unoenv_computeObjectIdentifier(
     868             :     uno_ExtEnvironment * pEnv, rtl_uString ** ppOId, void * pInterface )
     869             : {
     870             :     OSL_ENSURE( pEnv && ppOId && pInterface, "### null ptr!" );
     871        1662 :     if (*ppOId)
     872             :     {
     873           0 :         ::rtl_uString_release( *ppOId );
     874           0 :         *ppOId = 0;
     875             :     }
     876             : 
     877             :     uno_Interface * pUnoI = (uno_Interface *)
     878             :         ::cppu::binuno_queryInterface(
     879             :             pInterface, *typelib_static_type_getByTypeClass(
     880        1662 :                 typelib_TypeClass_INTERFACE ) );
     881        1662 :     if (0 != pUnoI)
     882             :     {
     883        1662 :         (*pUnoI->release)( pUnoI );
     884             :         // interface
     885        1662 :         ::rtl::OUStringBuffer oid( 64 );
     886        1662 :         oid.append( reinterpret_cast< sal_Int64 >(pUnoI), 16 );
     887        1662 :         oid.append( static_cast< sal_Unicode >(';') );
     888             :         // environment[context]
     889        1662 :         oid.append( ((uno_Environment *) pEnv)->pTypeName );
     890        1662 :         oid.append( static_cast< sal_Unicode >('[') );
     891             :         oid.append( reinterpret_cast< sal_Int64 >(
     892             :                         reinterpret_cast<
     893        1662 :                         uno_Environment * >(pEnv)->pContext ), 16 );
     894             :         // process;good guid
     895        1662 :         oid.append( unoenv_getStaticOIdPart() );
     896        1662 :         OUString aStr( oid.makeStringAndClear() );
     897        1662 :         ::rtl_uString_acquire( *ppOId = aStr.pData );
     898             :     }
     899        1662 : }
     900             : 
     901             : //==============================================================================
     902        1832 : static void SAL_CALL unoenv_acquireInterface(
     903             :     SAL_UNUSED_PARAMETER uno_ExtEnvironment *, void * pUnoI_ )
     904             : {
     905        1832 :     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
     906        1832 :     (*pUnoI->acquire)( pUnoI );
     907        1832 : }
     908             : 
     909             : //==============================================================================
     910        1662 : static void SAL_CALL unoenv_releaseInterface(
     911             :     SAL_UNUSED_PARAMETER uno_ExtEnvironment *, void * pUnoI_ )
     912             : {
     913        1662 :     uno_Interface * pUnoI = reinterpret_cast< uno_Interface * >(pUnoI_);
     914        1662 :     (*pUnoI->release)( pUnoI );
     915        1662 : }
     916             : }
     917             : 
     918             : //______________________________________________________________________________
     919         514 : EnvironmentsData::~EnvironmentsData()
     920             : {
     921         257 :     ::osl::MutexGuard guard( mutex );
     922         257 :     isDisposing = true;
     923             : 
     924        1596 :     for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
     925        1064 :           iPos != aName2EnvMap.end(); ++iPos )
     926             :     {
     927         275 :         uno_Environment * pWeak = iPos->second;
     928         275 :         uno_Environment * pHard = 0;
     929         275 :         (*pWeak->harden)( &pHard, pWeak );
     930         275 :         (*pWeak->releaseWeak)( pWeak );
     931             : 
     932         275 :         if (pHard)
     933             :         {
     934             : #if OSL_DEBUG_LEVEL > 1
     935             :             ::uno_dumpEnvironment( 0, pHard, 0 );
     936             : #endif
     937           0 :             (*pHard->dispose)( pHard ); // send explicit dispose
     938           0 :             (*pHard->release)( pHard );
     939             :         }
     940         257 :     }
     941         257 : }
     942             : 
     943             : //______________________________________________________________________________
     944       14664 : inline void EnvironmentsData::getEnvironment(
     945             :     uno_Environment ** ppEnv, const OUString & rEnvDcp, void * pContext )
     946             : {
     947       14664 :     if (*ppEnv)
     948             :     {
     949           0 :         (*(*ppEnv)->release)( *ppEnv );
     950           0 :         *ppEnv = 0;
     951             :     }
     952             : 
     953             :     OUString aKey(
     954       14664 :         OUString::valueOf( reinterpret_cast< sal_IntPtr >(pContext) ) );
     955       14664 :     aKey += rEnvDcp;
     956             : 
     957             :     // try to find registered mapping
     958             :     OUString2EnvironmentMap::const_iterator const iFind(
     959       14664 :         aName2EnvMap.find( aKey ) );
     960       14664 :     if (iFind != aName2EnvMap.end())
     961             :     {
     962       14389 :         uno_Environment * pWeak = iFind->second;
     963       14389 :         (*pWeak->harden)( ppEnv, pWeak );
     964       14664 :     }
     965       14664 : }
     966             : 
     967             : //______________________________________________________________________________
     968        6173 : inline void EnvironmentsData::registerEnvironment( uno_Environment ** ppEnv )
     969             : {
     970             :     OSL_ENSURE( ppEnv, "### null ptr!" );
     971        6173 :     uno_Environment * pEnv =  *ppEnv;
     972             : 
     973             :     OUString aKey(
     974        6173 :         OUString::valueOf( reinterpret_cast< sal_IntPtr >(pEnv->pContext) ) );
     975        6173 :     aKey += pEnv->pTypeName;
     976             : 
     977             :     // try to find registered environment
     978             :     OUString2EnvironmentMap::const_iterator const iFind(
     979        6173 :         aName2EnvMap.find( aKey ) );
     980        6173 :     if (iFind == aName2EnvMap.end())
     981             :     {
     982         275 :         (*pEnv->acquireWeak)( pEnv );
     983             :         ::std::pair< OUString2EnvironmentMap::iterator, bool > insertion (
     984             :             aName2EnvMap.insert(
     985         275 :                 OUString2EnvironmentMap::value_type( aKey, pEnv ) ) );
     986             :         SAL_WARN_IF( !insertion.second, "cppu", "key " << aKey << " already in env map" );
     987             :     }
     988             :     else
     989             :     {
     990        5898 :         uno_Environment * pHard = 0;
     991        5898 :         uno_Environment * pWeak = iFind->second;
     992        5898 :         (*pWeak->harden)( &pHard, pWeak );
     993        5898 :         if (pHard)
     994             :         {
     995           0 :             if (pEnv)
     996           0 :                 (*pEnv->release)( pEnv );
     997           0 :             *ppEnv = pHard;
     998             :         }
     999             :         else // registered one is dead
    1000             :         {
    1001        5898 :             (*pWeak->releaseWeak)( pWeak );
    1002        5898 :             (*pEnv->acquireWeak)( pEnv );
    1003        5898 :             aName2EnvMap[ aKey ] = pEnv;
    1004             :         }
    1005        6173 :     }
    1006        6173 : }
    1007             : 
    1008             : //______________________________________________________________________________
    1009           0 : inline void EnvironmentsData::getRegisteredEnvironments(
    1010             :     uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
    1011             :     const OUString & rEnvDcp )
    1012             : {
    1013             :     OSL_ENSURE( pppEnvs && pnLen && memAlloc, "### null ptr!" );
    1014             : 
    1015             :     // max size
    1016           0 :     uno_Environment ** ppFound = (uno_Environment **)alloca(
    1017             :         sizeof(uno_Environment *) * aName2EnvMap.size() );
    1018           0 :     sal_Int32 nSize = 0;
    1019             : 
    1020             :     // find matching environment
    1021           0 :     for ( OUString2EnvironmentMap::const_iterator iPos( aName2EnvMap.begin() );
    1022           0 :           iPos != aName2EnvMap.end(); ++iPos )
    1023             :     {
    1024           0 :         uno_Environment * pWeak = iPos->second;
    1025           0 :         if (rEnvDcp.isEmpty() ||
    1026           0 :             rEnvDcp.equals( pWeak->pTypeName ))
    1027             :         {
    1028           0 :             ppFound[nSize] = 0;
    1029           0 :             (*pWeak->harden)( &ppFound[nSize], pWeak );
    1030           0 :             if (ppFound[nSize])
    1031           0 :                 ++nSize;
    1032             :         }
    1033             :     }
    1034             : 
    1035           0 :     *pnLen = nSize;
    1036           0 :     if (nSize)
    1037             :     {
    1038             :         *pppEnvs = (uno_Environment **) (*memAlloc)(
    1039           0 :             sizeof (uno_Environment *) * nSize );
    1040             :         OSL_ASSERT( *pppEnvs );
    1041           0 :         while (nSize--)
    1042             :         {
    1043           0 :             (*pppEnvs)[nSize] = ppFound[nSize];
    1044             :         }
    1045             :     }
    1046             :     else
    1047             :     {
    1048           0 :         *pppEnvs = 0;
    1049             :     }
    1050           0 : }
    1051             : 
    1052        4425 : static bool loadEnv(OUString const  & cLibStem,
    1053             :                     uno_Environment * pEnv)
    1054             : {
    1055             : #ifdef DISABLE_DYNLOADING
    1056             :     oslModule hMod;
    1057             :     uno_initEnvironmentFunc fpInit;
    1058             : 
    1059             :     if ( cLibStem == CPPU_CURRENT_LANGUAGE_BINDING_NAME "_uno" )
    1060             :         fpInit = CPPU_ENV_uno_initEnvironment;
    1061             : #ifdef SOLAR_JAVA
    1062             :     else if ( cLibStem == "java_uno" )
    1063             :         fpInit = java_uno_initEnvironment;
    1064             : #endif
    1065             :     else
    1066             :     {
    1067             : #if OSL_DEBUG_LEVEL > 1
    1068             :         OSL_TRACE( "%s: Unhandled env: %s", __PRETTY_FUNCTION__, OUStringToOString( cLibStem, RTL_TEXTENCODING_ASCII_US).getStr() );
    1069             : #endif
    1070             :         return false;
    1071             :     }
    1072             :     // In the DISABLE_DYNLOADING case the functions that hMod is
    1073             :     // passed to below don't do anything with it anyway.
    1074             :     hMod = 0;
    1075             : #else
    1076             :     // late init with some code from matching uno language binding
    1077             :     // will be unloaded by environment
    1078        4425 :     oslModule hMod = cppu::detail::loadModule( cLibStem );
    1079             : 
    1080        4425 :     if (!hMod)
    1081           0 :         return false;
    1082             : 
    1083        4425 :     OUString aSymbolName(RTL_CONSTASCII_USTRINGPARAM(UNO_INIT_ENVIRONMENT));
    1084             :     uno_initEnvironmentFunc fpInit = (uno_initEnvironmentFunc)
    1085        4425 :         ::osl_getFunctionSymbol( hMod, aSymbolName.pData );
    1086             : 
    1087        4425 :     if (!fpInit)
    1088             :     {
    1089           0 :         ::osl_unloadModule( hMod );
    1090           0 :         return false;
    1091             :     }
    1092             : #endif
    1093             : 
    1094        4425 :     (*fpInit)( pEnv ); // init of environment
    1095        4425 :     ::rtl_registerModuleForUnloading( hMod );
    1096             : 
    1097        4425 :     return true;
    1098             : }
    1099             : 
    1100             : 
    1101             : extern "C"
    1102             : {
    1103             : 
    1104             : //------------------------------------------------------------------------------
    1105        6175 : static uno_Environment * initDefaultEnvironment(
    1106             :     const OUString & rEnvDcp, void * pContext )
    1107             : {
    1108        6175 :     uno_Environment * pEnv = &(new uno_DefaultEnvironment( rEnvDcp, pContext ))->aBase;
    1109        6175 :     (*pEnv->acquire)( pEnv );
    1110             : 
    1111        6175 :     OUString envTypeName = cppu::EnvDcp::getTypeName(rEnvDcp);
    1112             : 
    1113             :     // create default environment
    1114        6175 :     if ( envTypeName == UNO_LB_UNO )
    1115             :     {
    1116        1750 :         uno_DefaultEnvironment * that = (uno_DefaultEnvironment *)pEnv;
    1117        1750 :         that->computeObjectIdentifier = unoenv_computeObjectIdentifier;
    1118        1750 :         that->acquireInterface = unoenv_acquireInterface;
    1119        1750 :         that->releaseInterface = unoenv_releaseInterface;
    1120             : 
    1121        1750 :         OUString envPurpose = cppu::EnvDcp::getPurpose(rEnvDcp);
    1122        1750 :         if (!envPurpose.isEmpty())
    1123             :         {
    1124           0 :             rtl::OUString libStem = envPurpose.copy(envPurpose.lastIndexOf(':') + 1);
    1125           0 :             libStem += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("_uno_uno") );
    1126             : 
    1127           0 :             if(!loadEnv(libStem, pEnv))
    1128             :             {
    1129           0 :                 pEnv->release(pEnv);
    1130           0 :                 return NULL;
    1131           0 :             }
    1132        1750 :         }
    1133             :     }
    1134             :     else
    1135             :     {
    1136             :         // late init with some code from matching uno language binding
    1137        4425 :         ::rtl::OUStringBuffer aLibName( 16 );
    1138        4425 :         aLibName.append( envTypeName );
    1139        4425 :         aLibName.appendAscii( RTL_CONSTASCII_STRINGPARAM("_uno" ) );
    1140        4425 :         OUString aStr( aLibName.makeStringAndClear() );
    1141             : 
    1142        4425 :         if (!loadEnv(aStr, pEnv))
    1143             :         {
    1144           0 :             pEnv->release(pEnv);
    1145           0 :             return NULL;
    1146        4425 :         }
    1147             :     }
    1148             : 
    1149        6175 :     return pEnv;
    1150             : }
    1151             : 
    1152             : //##############################################################################
    1153           2 : CPPU_DLLPUBLIC void SAL_CALL uno_createEnvironment(
    1154             :     uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
    1155             :     SAL_THROW_EXTERN_C()
    1156             : {
    1157             :     OSL_ENSURE( ppEnv, "### null ptr!" );
    1158           2 :     if (*ppEnv)
    1159           0 :         (*(*ppEnv)->release)( *ppEnv );
    1160             : 
    1161           2 :     OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
    1162           2 :     *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
    1163           2 : }
    1164             : 
    1165             : //##############################################################################
    1166       14664 : void SAL_CALL uno_direct_getEnvironment(
    1167             :     uno_Environment ** ppEnv, rtl_uString * pEnvDcp, void * pContext )
    1168             :     SAL_THROW_EXTERN_C()
    1169             : {
    1170             :     OSL_ENSURE( ppEnv, "### null ptr!" );
    1171       14664 :     OUString const & rEnvDcp = OUString::unacquired( &pEnvDcp );
    1172             : 
    1173       14664 :     EnvironmentsData & rData = theEnvironmentsData::get();
    1174             : 
    1175       14664 :     ::osl::MutexGuard guard( rData.mutex );
    1176       14664 :     rData.getEnvironment( ppEnv, rEnvDcp, pContext );
    1177       14664 :     if (! *ppEnv)
    1178             :     {
    1179        6173 :         *ppEnv = initDefaultEnvironment( rEnvDcp, pContext );
    1180        6173 :         if (*ppEnv)
    1181             :         {
    1182             :             // register new environment:
    1183        6173 :             rData.registerEnvironment( ppEnv );
    1184             :         }
    1185       14664 :     }
    1186       14664 : }
    1187             : 
    1188             : //##############################################################################
    1189           0 : CPPU_DLLPUBLIC void SAL_CALL uno_getRegisteredEnvironments(
    1190             :     uno_Environment *** pppEnvs, sal_Int32 * pnLen, uno_memAlloc memAlloc,
    1191             :     rtl_uString * pEnvDcp )
    1192             :     SAL_THROW_EXTERN_C()
    1193             : {
    1194           0 :     EnvironmentsData & rData = theEnvironmentsData::get();
    1195             : 
    1196           0 :     ::osl::MutexGuard guard( rData.mutex );
    1197             :     rData.getRegisteredEnvironments(
    1198             :         pppEnvs, pnLen, memAlloc,
    1199           0 :         (pEnvDcp ? OUString(pEnvDcp) : OUString()) );
    1200           0 : }
    1201             : 
    1202             : } // extern "C"
    1203             : 
    1204             : }
    1205             : 
    1206             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10