LCOV - code coverage report
Current view: top level - cppu/source/uno - EnvStack.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 76 177 42.9 %
Date: 2012-08-25 Functions: 10 20 50.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 42 163 25.8 %

           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                 :            : #include "uno/environment.hxx"
      21                 :            : 
      22                 :            : #include "cppu/EnvDcp.hxx"
      23                 :            : #include "cppu/Enterable.hxx"
      24                 :            : 
      25                 :            : #include "rtl/instance.hxx"
      26                 :            : 
      27                 :            : #include "osl/thread.h"
      28                 :            : #include "osl/mutex.hxx"
      29                 :            : 
      30                 :            : #include <boost/unordered_map.hpp>
      31                 :            : 
      32                 :            : 
      33                 :            : using namespace com::sun::star;
      34                 :            : 
      35                 :            : 
      36                 :            : struct SAL_DLLPRIVATE oslThreadIdentifier_equal
      37                 :            : {
      38                 :            :     bool operator()(oslThreadIdentifier s1, oslThreadIdentifier s2) const;
      39                 :            : };
      40                 :            : 
      41                 :          0 : bool oslThreadIdentifier_equal::operator()(oslThreadIdentifier s1, oslThreadIdentifier s2) const
      42                 :            : {
      43                 :          0 :     bool result = s1 == s2;
      44                 :            : 
      45                 :          0 :     return result;
      46                 :            : }
      47                 :            : 
      48                 :            : 
      49                 :            : struct SAL_DLLPRIVATE oslThreadIdentifier_hash
      50                 :            : {
      51                 :            :     size_t operator()(oslThreadIdentifier s1) const;
      52                 :            : };
      53                 :            : 
      54                 :          0 : size_t oslThreadIdentifier_hash::operator()(oslThreadIdentifier s1) const
      55                 :            : {
      56                 :          0 :     return s1;
      57                 :            : }
      58                 :            : 
      59                 :            : typedef ::boost::unordered_map<oslThreadIdentifier,
      60                 :            :                         uno_Environment *,
      61                 :            :                         oslThreadIdentifier_hash,
      62                 :            :                         oslThreadIdentifier_equal>  ThreadMap;
      63                 :            : 
      64                 :            : namespace
      65                 :            : {
      66                 :            :     struct s_threadMap_mutex : public rtl::Static< osl::Mutex, s_threadMap_mutex > {};
      67                 :            :     struct s_threadMap : public rtl::Static< ThreadMap, s_threadMap > {};
      68                 :            : }
      69                 :            : 
      70                 :       2411 : static rtl::OUString s_uno_envDcp(RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO));
      71                 :            : 
      72                 :    2015721 : static void s_setCurrent(uno_Environment * pEnv)
      73                 :            : {
      74         [ +  - ]:    2015721 :     oslThreadIdentifier threadId = osl_getThreadIdentifier(NULL);
      75                 :            : 
      76 [ +  - ][ +  - ]:    2015722 :     osl::MutexGuard guard(s_threadMap_mutex::get());
      77         [ +  - ]:    2015722 :     ThreadMap &rThreadMap = s_threadMap::get();
      78         [ -  + ]:    2015722 :     if (pEnv)
      79         [ #  # ]:          0 :         rThreadMap[threadId] = pEnv;
      80                 :            : 
      81                 :            :     else
      82 [ +  - ][ +  - ]:    2015722 :         rThreadMap.erase(threadId);
      83                 :    2015722 : }
      84                 :            : 
      85                 :    2070878 : static uno_Environment * s_getCurrent(void)
      86                 :            : {
      87                 :    2070878 :     uno_Environment * pEnv = NULL;
      88                 :            : 
      89         [ +  - ]:    2070878 :     oslThreadIdentifier threadId = osl_getThreadIdentifier(NULL);
      90                 :            : 
      91 [ +  - ][ +  - ]:    2070882 :     osl::MutexGuard guard(s_threadMap_mutex::get());
      92         [ +  - ]:    2070882 :     ThreadMap &rThreadMap = s_threadMap::get();
      93         [ +  - ]:    2070882 :     ThreadMap::iterator iEnv = rThreadMap.find(threadId);
      94 [ +  - ][ -  + ]:    2070882 :     if(iEnv != rThreadMap.end())
      95         [ #  # ]:          0 :         pEnv = iEnv->second;
      96                 :            : 
      97         [ +  - ]:    2070882 :     return pEnv;
      98                 :            : }
      99                 :            : 
     100                 :            : 
     101                 :      55160 : extern "C" CPPU_DLLPUBLIC void SAL_CALL uno_getCurrentEnvironment(uno_Environment ** ppEnv, rtl_uString * pTypeName)
     102                 :            :     SAL_THROW_EXTERN_C()
     103                 :            : {
     104         [ -  + ]:      55160 :     if (*ppEnv)
     105                 :            :     {
     106         [ #  # ]:          0 :         (*ppEnv)->release(*ppEnv);
     107                 :          0 :         *ppEnv = NULL;
     108                 :            :     }
     109                 :            : 
     110                 :      55160 :     rtl::OUString currPurpose;
     111                 :            : 
     112         [ +  - ]:      55160 :     uno_Environment * pCurrEnv = s_getCurrent();
     113         [ -  + ]:      55160 :     if (pCurrEnv) // no environment means no purpose
     114         [ #  # ]:          0 :         currPurpose = cppu::EnvDcp::getPurpose(pCurrEnv->pTypeName);
     115                 :            : 
     116 [ +  - ][ +  - ]:      55160 :     if (pTypeName && rtl_uString_getLength(pTypeName))
                 [ +  - ]
     117                 :            :     {
     118                 :      55160 :         rtl::OUString envDcp(pTypeName);
     119                 :      55160 :         envDcp += currPurpose;
     120                 :            : 
     121                 :      55160 :         uno_getEnvironment(ppEnv, envDcp.pData, NULL);
     122                 :            :     }
     123                 :            :     else
     124                 :            :     {
     125         [ #  # ]:          0 :         if (pCurrEnv)
     126                 :            :         {
     127                 :          0 :             *ppEnv = pCurrEnv;
     128         [ #  # ]:          0 :             (*ppEnv)->acquire(*ppEnv);
     129                 :            :         }
     130                 :            :         else
     131                 :          0 :             uno_getEnvironment(ppEnv, s_uno_envDcp.pData, NULL);
     132                 :            : 
     133                 :      55160 :     }
     134                 :      55160 : }
     135                 :            : 
     136                 :    1007861 : static rtl::OUString s_getPrefix(rtl::OUString const & str1, rtl::OUString const & str2)
     137                 :            : {
     138                 :    1007861 :     sal_Int32 nIndex1 = 0;
     139                 :    1007861 :     sal_Int32 nIndex2 = 0;
     140                 :    1007861 :     sal_Int32 sim = 0;
     141                 :            : 
     142                 :    1007861 :     rtl::OUString token1;
     143                 :    1007861 :     rtl::OUString token2;
     144                 :            : 
     145         [ +  - ]:    1007861 :     do
           [ -  +  #  # ]
                 [ -  + ]
     146                 :            :     {
     147                 :    1007861 :         token1 = str1.getToken(0, ':', nIndex1);
     148                 :    1007861 :         token2 = str2.getToken(0, ':', nIndex2);
     149                 :            : 
     150         [ +  - ]:    1007861 :         if (token1.equals(token2))
     151                 :    1007861 :             sim += token1.getLength() + 1;
     152                 :            :     }
     153                 :          0 :     while(nIndex1 == nIndex2 && nIndex1 >= 0 && token1.equals(token2));
     154                 :            : 
     155                 :    1007861 :     rtl::OUString result;
     156                 :            : 
     157         [ +  - ]:    1007861 :     if (sim)
     158                 :    1007861 :         result = str1.copy(0, sim - 1);
     159                 :            : 
     160                 :    1007861 :     return result;
     161                 :            : }
     162                 :            : 
     163                 :    1007861 : static int s_getNextEnv(uno_Environment ** ppEnv, uno_Environment * pCurrEnv, uno_Environment * pTargetEnv)
     164                 :            : {
     165                 :    1007861 :     int res = 0;
     166                 :            : 
     167                 :    1007861 :     rtl::OUString nextPurpose;
     168                 :            : 
     169                 :    1007861 :     rtl::OUString currPurpose;
     170         [ -  + ]:    1007861 :     if (pCurrEnv)
     171         [ #  # ]:          0 :         currPurpose = cppu::EnvDcp::getPurpose(pCurrEnv->pTypeName);
     172                 :            : 
     173                 :    1007861 :     rtl::OUString targetPurpose;
     174         [ +  - ]:    1007861 :     if (pTargetEnv)
     175         [ +  - ]:    1007861 :         targetPurpose = cppu::EnvDcp::getPurpose(pTargetEnv->pTypeName);
     176                 :            : 
     177                 :    1007861 :     rtl::OUString intermPurpose(s_getPrefix(currPurpose, targetPurpose));
     178         [ -  + ]:    1007861 :     if (currPurpose.getLength() > intermPurpose.getLength())
     179                 :            :     {
     180                 :          0 :         sal_Int32 idx = currPurpose.lastIndexOf(':');
     181                 :          0 :         nextPurpose = currPurpose.copy(0, idx);
     182                 :            : 
     183                 :          0 :         res = -1;
     184                 :            :     }
     185         [ -  + ]:    1007861 :     else if (intermPurpose.getLength() < targetPurpose.getLength())
     186                 :            :     {
     187                 :          0 :         sal_Int32 idx = targetPurpose.indexOf(':', intermPurpose.getLength() + 1);
     188         [ #  # ]:          0 :         if (idx == -1)
     189                 :          0 :             nextPurpose = targetPurpose;
     190                 :            : 
     191                 :            :         else
     192                 :          0 :             nextPurpose = targetPurpose.copy(0, idx);
     193                 :            : 
     194                 :          0 :         res = 1;
     195                 :            :     }
     196                 :            : 
     197         [ -  + ]:    1007861 :     if (!nextPurpose.isEmpty())
     198                 :            :     {
     199                 :          0 :         rtl::OUString next_envDcp(s_uno_envDcp);
     200                 :          0 :         next_envDcp += nextPurpose;
     201                 :            : 
     202                 :          0 :         uno_getEnvironment(ppEnv, next_envDcp.pData, NULL);
     203                 :            :     }
     204                 :            :     else
     205                 :            :     {
     206         [ -  + ]:    1007861 :         if (*ppEnv)
     207         [ #  # ]:          0 :             (*ppEnv)->release(*ppEnv);
     208                 :            : 
     209                 :    1007861 :         *ppEnv = NULL;
     210                 :            :     }
     211                 :            : 
     212                 :    1007861 :     return res;
     213                 :            : }
     214                 :            : 
     215                 :          0 : extern "C" { static void s_pull(va_list * pParam)
     216                 :            : {
     217                 :          0 :     uno_EnvCallee * pCallee = va_arg(*pParam, uno_EnvCallee *);
     218                 :          0 :     va_list       * pXparam = va_arg(*pParam, va_list *);
     219                 :            : 
     220                 :          0 :     pCallee(pXparam);
     221                 :          0 : }}
     222                 :            : 
     223                 :          0 : static void s_callInto_v(uno_Environment * pEnv, uno_EnvCallee * pCallee, va_list * pParam)
     224                 :            : {
     225                 :          0 :     cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved);
     226         [ #  # ]:          0 :     if (pEnterable)
     227                 :          0 :         pEnterable->callInto(s_pull, pCallee, pParam);
     228                 :            : 
     229                 :            :     else
     230                 :          0 :         pCallee(pParam);
     231                 :          0 : }
     232                 :            : 
     233                 :          0 : static void s_callInto(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...)
     234                 :            : {
     235                 :            :     va_list param;
     236                 :            : 
     237                 :          0 :     va_start(param, pCallee);
     238         [ #  # ]:          0 :     s_callInto_v(pEnv, pCallee, &param);
     239                 :          0 :     va_end(param);
     240                 :          0 : }
     241                 :            : 
     242                 :          0 : static void s_callOut_v(uno_Environment * pEnv, uno_EnvCallee * pCallee, va_list * pParam)
     243                 :            : {
     244                 :          0 :     cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved);
     245         [ #  # ]:          0 :     if (pEnterable)
     246                 :          0 :         pEnterable->callOut_v(pCallee, pParam);
     247                 :            : 
     248                 :            :     else
     249                 :          0 :         pCallee(pParam);
     250                 :          0 : }
     251                 :            : 
     252                 :          0 : static void s_callOut(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...)
     253                 :            : {
     254                 :            :     va_list param;
     255                 :            : 
     256                 :          0 :     va_start(param, pCallee);
     257         [ #  # ]:          0 :     s_callOut_v(pEnv, pCallee, &param);
     258                 :          0 :     va_end(param);
     259                 :          0 : }
     260                 :            : 
     261                 :            : static void s_environment_invoke_v(uno_Environment *, uno_Environment *, uno_EnvCallee *, va_list *);
     262                 :            : 
     263                 :          0 : extern "C" { static void s_environment_invoke_vv(va_list * pParam)
     264                 :            : {
     265                 :          0 :     uno_Environment * pCurrEnv    = va_arg(*pParam, uno_Environment *);
     266                 :          0 :     uno_Environment * pTargetEnv  = va_arg(*pParam, uno_Environment *);
     267                 :          0 :     uno_EnvCallee   * pCallee     = va_arg(*pParam, uno_EnvCallee *);
     268                 :          0 :     va_list         * pXparam     = va_arg(*pParam, va_list *);
     269                 :            : 
     270                 :          0 :     s_environment_invoke_v(pCurrEnv, pTargetEnv, pCallee, pXparam);
     271                 :          0 : }}
     272                 :            : 
     273                 :    1007861 : static void s_environment_invoke_v(uno_Environment * pCurrEnv, uno_Environment * pTargetEnv, uno_EnvCallee * pCallee, va_list * pParam)
     274                 :            : {
     275                 :    1007861 :     uno_Environment * pNextEnv = NULL;
     276         [ +  - ]:    1007861 :     switch(s_getNextEnv(&pNextEnv, pCurrEnv, pTargetEnv))
           [ -  +  -  - ]
     277                 :            :     {
     278                 :            :     case -1:
     279         [ #  # ]:          0 :         s_setCurrent(pNextEnv);
     280         [ #  # ]:          0 :         s_callOut(pCurrEnv, s_environment_invoke_vv, pNextEnv, pTargetEnv, pCallee, pParam);
     281         [ #  # ]:          0 :         s_setCurrent(pCurrEnv);
     282                 :          0 :         break;
     283                 :            : 
     284                 :            :     case 0: {
     285         [ +  - ]:    1007861 :         uno_Environment * hld = s_getCurrent();
     286         [ +  - ]:    1007860 :         s_setCurrent(pCurrEnv);
     287         [ +  - ]:    1007861 :         pCallee(pParam);
     288         [ +  - ]:    1007861 :         s_setCurrent(hld);
     289                 :            :     }
     290                 :    1007861 :         break;
     291                 :            : 
     292                 :            :     case 1:
     293         [ #  # ]:          0 :         s_setCurrent(pNextEnv);
     294         [ #  # ]:          0 :         s_callInto(pNextEnv, s_environment_invoke_vv, pNextEnv, pTargetEnv, pCallee, pParam);
     295         [ #  # ]:          0 :         s_setCurrent(pCurrEnv);
     296                 :          0 :         break;
     297                 :            :     }
     298                 :            : 
     299         [ -  + ]:    1007861 :     if (pNextEnv)
     300         [ #  # ]:          0 :         pNextEnv->release(pNextEnv);
     301                 :    1007861 : }
     302                 :            : 
     303                 :    1007861 : extern "C" CPPU_DLLPUBLIC void SAL_CALL uno_Environment_invoke_v(uno_Environment * pTargetEnv, uno_EnvCallee * pCallee, va_list * pParam)
     304                 :            :     SAL_THROW_EXTERN_C()
     305                 :            : {
     306                 :    1007861 :     s_environment_invoke_v(s_getCurrent(), pTargetEnv, pCallee, pParam);
     307                 :    1007861 : }
     308                 :            : 
     309                 :     977204 : extern "C" CPPU_DLLPUBLIC void SAL_CALL uno_Environment_invoke(uno_Environment * pEnv, uno_EnvCallee * pCallee, ...)
     310                 :            :     SAL_THROW_EXTERN_C()
     311                 :            : {
     312                 :            :     va_list param;
     313                 :            : 
     314                 :     977204 :     va_start(param, pCallee);
     315                 :     977204 :     uno_Environment_invoke_v(pEnv, pCallee, &param);
     316                 :     977204 :     va_end(param);
     317                 :     977204 : }
     318                 :            : 
     319                 :          0 : extern "C" CPPU_DLLPUBLIC void SAL_CALL uno_Environment_enter(uno_Environment * pTargetEnv)
     320                 :            :     SAL_THROW_EXTERN_C()
     321                 :            : {
     322                 :          0 :     uno_Environment * pNextEnv = NULL;
     323         [ #  # ]:          0 :     uno_Environment * pCurrEnv = s_getCurrent();
     324                 :            : 
     325                 :            :     int res;
     326 [ #  # ][ #  # ]:          0 :     while ( (res = s_getNextEnv(&pNextEnv, pCurrEnv, pTargetEnv)) != 0)
     327                 :            :     {
     328                 :            :         cppu::Enterable * pEnterable;
     329                 :            : 
     330      [ #  #  # ]:          0 :         switch(res)
     331                 :            :         {
     332                 :            :         case -1:
     333                 :          0 :             pEnterable = reinterpret_cast<cppu::Enterable *>(pCurrEnv->pReserved);
     334         [ #  # ]:          0 :             if (pEnterable)
     335         [ #  # ]:          0 :                 pEnterable->leave();
     336         [ #  # ]:          0 :             pCurrEnv->release(pCurrEnv);
     337                 :          0 :             break;
     338                 :            : 
     339                 :            :         case 1:
     340         [ #  # ]:          0 :             pNextEnv->acquire(pNextEnv);
     341                 :          0 :             pEnterable = reinterpret_cast<cppu::Enterable *>(pNextEnv->pReserved);
     342         [ #  # ]:          0 :             if (pEnterable)
     343         [ #  # ]:          0 :                 pEnterable->enter();
     344                 :          0 :             break;
     345                 :            :         }
     346                 :            : 
     347         [ #  # ]:          0 :         s_setCurrent(pNextEnv);
     348                 :          0 :         pCurrEnv = pNextEnv;
     349                 :            :     }
     350                 :          0 : }
     351                 :            : 
     352                 :          0 : CPPU_DLLPUBLIC int SAL_CALL uno_Environment_isValid(uno_Environment * pEnv, rtl_uString ** pReason)
     353                 :            :     SAL_THROW_EXTERN_C()
     354                 :            : {
     355                 :          0 :     int result = 1;
     356                 :            : 
     357         [ #  # ]:          0 :     rtl::OUString typeName(cppu::EnvDcp::getTypeName(pEnv->pTypeName));
     358         [ #  # ]:          0 :     if (typeName.equals(s_uno_envDcp))
     359                 :            :     {
     360                 :          0 :         cppu::Enterable * pEnterable = reinterpret_cast<cppu::Enterable *>(pEnv->pReserved);
     361         [ #  # ]:          0 :         if (pEnterable)
     362         [ #  # ]:          0 :             result = pEnterable->isValid((rtl::OUString *)pReason);
     363                 :            :     }
     364                 :            :     else
     365                 :            :     {
     366                 :          0 :         rtl::OUString envDcp(s_uno_envDcp);
     367         [ #  # ]:          0 :         envDcp += cppu::EnvDcp::getPurpose(pEnv->pTypeName);
     368                 :            : 
     369                 :          0 :         uno::Environment env(envDcp);
     370                 :            : 
     371         [ #  # ]:          0 :         result = env.isValid((rtl::OUString *)pReason);
     372                 :            :     }
     373                 :            : 
     374                 :          0 :     return result;
     375 [ +  - ][ +  - ]:       7233 : }
     376                 :            : 
     377                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10