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

Generated by: LCOV version 1.10