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

Generated by: LCOV version 1.11