LCOV - code coverage report
Current view: top level - cppu/source/uno - lbenv.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 339 489 69.3 %
Date: 2012-08-25 Functions: 36 44 81.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 226 597 37.9 %

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

Generated by: LCOV version 1.10