LCOV - code coverage report
Current view: top level - comphelper/source/misc - numberedcollection.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 71 91 78.0 %
Date: 2012-08-25 Functions: 10 11 90.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 70 179 39.1 %

           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 <comphelper/numberedcollection.hxx>
      22                 :            : 
      23                 :            : #include <com/sun/star/frame/UntitledNumbersConst.hpp>
      24                 :            : 
      25                 :            : 
      26                 :            : namespace comphelper{
      27                 :            : 
      28                 :            : namespace css = ::com::sun::star;
      29                 :            : 
      30                 :            : 
      31                 :            : static const char ERRMSG_INVALID_COMPONENT_PARAM[] = "NULL as component reference not allowed.";
      32                 :            : 
      33                 :            : //-----------------------------------------------
      34                 :       1945 : NumberedCollection::NumberedCollection()
      35                 :            :     : ::cppu::BaseMutex ()
      36                 :            :     , m_sUntitledPrefix ()
      37                 :            :     , m_lComponents     ()
      38 [ +  - ][ +  - ]:       1945 :     , m_xOwner          ()
                 [ +  - ]
      39                 :            : {
      40                 :       1945 : }
      41                 :            : 
      42                 :            : //-----------------------------------------------
      43 [ +  - ][ +  - ]:       1792 : NumberedCollection::~NumberedCollection()
                 [ +  - ]
      44                 :            : {
      45         [ -  + ]:       3584 : }
      46                 :            : 
      47                 :            : //-----------------------------------------------
      48                 :       1945 : void NumberedCollection::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner)
      49                 :            : {
      50                 :            :     // SYNCHRONIZED ->
      51         [ +  - ]:       1945 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
      52                 :            : 
      53 [ +  - ][ +  - ]:       1945 :         m_xOwner = xOwner;
      54                 :            : 
      55                 :            :     // <- SYNCHRONIZED
      56                 :       1945 : }
      57                 :            : 
      58                 :            : //-----------------------------------------------
      59                 :       1945 : void NumberedCollection::setUntitledPrefix(const ::rtl::OUString& sPrefix)
      60                 :            : {
      61                 :            :     // SYNCHRONIZED ->
      62         [ +  - ]:       1945 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
      63                 :            : 
      64         [ +  - ]:       1945 :         m_sUntitledPrefix = sPrefix;
      65                 :            : 
      66                 :            :     // <- SYNCHRONIZED
      67                 :       1945 : }
      68                 :            : 
      69                 :            : //-----------------------------------------------
      70                 :       2831 : ::sal_Int32 SAL_CALL NumberedCollection::leaseNumber(const css::uno::Reference< css::uno::XInterface >& xComponent)
      71                 :            :     throw (css::lang::IllegalArgumentException,
      72                 :            :            css::uno::RuntimeException         )
      73                 :            : {
      74                 :            :     // SYNCHRONIZED ->
      75         [ +  - ]:       2831 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
      76                 :            : 
      77         [ -  + ]:       2831 :         if ( ! xComponent.is ())
      78 [ #  # ][ #  # ]:          0 :             throw css::lang::IllegalArgumentException (rtl::OUString(ERRMSG_INVALID_COMPONENT_PARAM), m_xOwner.get(), 1);
      79                 :            : 
      80         [ +  - ]:       2831 :         long                              pComponent = (long) xComponent.get ();
      81         [ +  - ]:       2831 :         TNumberedItemHash::const_iterator pIt        = m_lComponents.find (pComponent);
      82                 :            : 
      83                 :            :         // a) component already exists - return it's number directly
      84 [ -  + ][ +  - ]:       2831 :         if (pIt != m_lComponents.end())
      85         [ #  # ]:          0 :             return pIt->second.nNumber;
      86                 :            : 
      87                 :            :         // b) component must be added new to this container
      88                 :            : 
      89                 :            :         // b1) collection is full - no further components possible
      90                 :            :         //     -> return INVALID_NUMBER
      91         [ +  - ]:       2831 :         ::sal_Int32 nFreeNumber = impl_searchFreeNumber();
      92         [ -  + ]:       2831 :         if (nFreeNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER)
      93                 :          0 :             return css::frame::UntitledNumbersConst::INVALID_NUMBER;
      94                 :            : 
      95                 :            :         // b2) add component to collection and return its number
      96         [ +  - ]:       2831 :         TNumberedItem aItem;
      97 [ +  - ][ +  - ]:       2831 :         aItem.xItem   = css::uno::WeakReference< css::uno::XInterface >(xComponent);
                 [ +  - ]
      98                 :       2831 :         aItem.nNumber = nFreeNumber;
      99 [ +  - ][ +  - ]:       2831 :         m_lComponents[pComponent] = aItem;
     100                 :            : 
     101 [ +  - ][ +  - ]:       2831 :         return nFreeNumber;
     102                 :            : 
     103                 :            :     // <- SYNCHRONIZED
     104                 :            : }
     105                 :            : 
     106                 :            : //-----------------------------------------------
     107                 :       1100 : void SAL_CALL NumberedCollection::releaseNumber(::sal_Int32 nNumber)
     108                 :            :     throw (css::lang::IllegalArgumentException,
     109                 :            :            css::uno::RuntimeException         )
     110                 :            : {
     111                 :            :     // SYNCHRONIZED ->
     112         [ +  - ]:       1100 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     113                 :            : 
     114         [ -  + ]:       1100 :     if (nNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER)
     115 [ #  # ][ #  # ]:          0 :         throw css::lang::IllegalArgumentException (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Special valkud INVALID_NUMBER not allowed as input parameter.")), m_xOwner.get(), 1);
                 [ #  # ]
     116                 :            : 
     117         [ +  - ]:       1100 :     TDeadItemList               lDeadItems;
     118                 :       1100 :     TNumberedItemHash::iterator pComponent;
     119                 :            : 
     120 [ +  - ][ +  - ]:       2224 :     for (  pComponent  = m_lComponents.begin ();
     121         [ +  - ]:       1112 :            pComponent != m_lComponents.end   ();
     122                 :            :          ++pComponent                          )
     123                 :            :     {
     124         [ +  - ]:       1112 :         const TNumberedItem&                              rItem = pComponent->second;
     125         [ +  - ]:       1112 :         const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get();
     126                 :            : 
     127         [ -  + ]:       1112 :         if ( ! xItem.is ())
     128                 :            :         {
     129 [ #  # ][ #  # ]:          0 :             lDeadItems.push_back(pComponent->first);
     130                 :          0 :             continue;
     131                 :            :         }
     132                 :            : 
     133         [ +  + ]:       1112 :         if (rItem.nNumber == nNumber)
     134                 :            :         {
     135         [ +  - ]:       1112 :             m_lComponents.erase (pComponent);
     136                 :            :             break;
     137                 :            :         }
     138      [ +  -  + ]:       1112 :     }
     139                 :            : 
     140 [ +  - ][ +  - ]:       1100 :     impl_cleanUpDeadItems(m_lComponents, lDeadItems);
     141                 :            : 
     142                 :            :     // <- SYNCHRONIZED
     143                 :       1100 : }
     144                 :            : 
     145                 :            : //-----------------------------------------------
     146                 :          0 : void SAL_CALL NumberedCollection::releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent)
     147                 :            :     throw (css::lang::IllegalArgumentException,
     148                 :            :            css::uno::RuntimeException         )
     149                 :            : {
     150                 :            :     // SYNCHRONIZED ->
     151         [ #  # ]:          0 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     152                 :            : 
     153         [ #  # ]:          0 :         if ( ! xComponent.is ())
     154 [ #  # ][ #  # ]:          0 :             throw css::lang::IllegalArgumentException (rtl::OUString(ERRMSG_INVALID_COMPONENT_PARAM), m_xOwner.get(), 1);
     155                 :            : 
     156         [ #  # ]:          0 :         long                        pComponent = (long) xComponent.get ();
     157         [ #  # ]:          0 :         TNumberedItemHash::iterator pIt        = m_lComponents.find (pComponent);
     158                 :            : 
     159                 :            :         // a) component exists and will be removed
     160 [ #  # ][ #  # ]:          0 :         if (pIt != m_lComponents.end())
     161 [ #  # ][ #  # ]:          0 :             m_lComponents.erase(pIt);
     162                 :            : 
     163                 :            :         // else
     164                 :            :         // b) component does not exists - nothing todo here (ignore request!)
     165                 :            : 
     166                 :            :     // <- SYNCHRONIZED
     167                 :          0 : }
     168                 :            : 
     169                 :            : //-----------------------------------------------
     170                 :       4777 : ::rtl::OUString SAL_CALL NumberedCollection::getUntitledPrefix()
     171                 :            :     throw (css::uno::RuntimeException)
     172                 :            : {
     173                 :            :     // SYNCHRONIZED ->
     174         [ +  - ]:       4777 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     175                 :            : 
     176         [ +  - ]:       4777 :         return m_sUntitledPrefix;
     177                 :            : 
     178                 :            :     // <- SYNCHRONIZED
     179                 :            : }
     180                 :            : 
     181                 :            : //-----------------------------------------------
     182                 :            : /** create an ordered list of all possible numbers ...
     183                 :            :     e.g. {1,2,3,...,N} Max size of these list will be
     184                 :            :     current size of component list + 1 .
     185                 :            : 
     186                 :            :     "+1" ... because in case all numbers in range 1..n
     187                 :            :     are in use we need a new number n+1 :-)
     188                 :            : 
     189                 :            :     Every item which is already used as unique number
     190                 :            :     will be removed. At the end a list of e.g. {3,6,...,M}
     191                 :            :     exists where the first item represent the lowest free
     192                 :            :     number (in this example 3).
     193                 :            :  */
     194                 :       2831 : ::sal_Int32 NumberedCollection::impl_searchFreeNumber ()
     195                 :            : {
     196                 :            :     // create ordered list of all possible numbers.
     197         [ +  - ]:       2831 :     ::std::vector< ::sal_Int32 > lPossibleNumbers;
     198                 :       2831 :     ::sal_Int32                  c = (::sal_Int32)m_lComponents.size ();
     199                 :       2831 :     ::sal_Int32                  i = 1;
     200                 :            : 
     201                 :            :     // c cant be less then 0 ... otherwhise hash.size() has an error :-)
     202                 :            :     // But we need at least n+1 numbers here.
     203                 :       2831 :     c += 1;
     204                 :            : 
     205         [ +  + ]:       5886 :     for (i=1; i<=c; ++i)
     206         [ +  - ]:       3055 :         lPossibleNumbers.push_back (i);
     207                 :            : 
     208                 :            :     // SYNCHRONIZED ->
     209         [ +  - ]:       2831 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     210                 :            : 
     211         [ +  - ]:       2831 :         TDeadItemList                     lDeadItems;
     212                 :       2831 :         TNumberedItemHash::const_iterator pComponent;
     213                 :            : 
     214 [ +  + ][ +  - ]:       6110 :         for (  pComponent  = m_lComponents.begin ();
     215         [ +  - ]:       3055 :                pComponent != m_lComponents.end   ();
     216                 :            :              ++pComponent                          )
     217                 :            :         {
     218         [ +  - ]:        224 :             const TNumberedItem&                              rItem = pComponent->second;
     219         [ +  - ]:        224 :             const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get();
     220                 :            : 
     221         [ -  + ]:        224 :             if ( ! xItem.is ())
     222                 :            :             {
     223 [ #  # ][ #  # ]:          0 :                 lDeadItems.push_back(pComponent->first);
     224                 :          0 :                 continue;
     225                 :            :             }
     226                 :            : 
     227         [ +  - ]:        224 :             ::std::vector< ::sal_Int32 >::iterator pPossible = ::std::find(lPossibleNumbers.begin (), lPossibleNumbers.end (), rItem.nNumber);
     228 [ +  - ][ +  - ]:        224 :             if (pPossible != lPossibleNumbers.end ())
     229         [ +  - ]:        224 :                 lPossibleNumbers.erase (pPossible);
     230         [ +  - ]:        224 :         }
     231                 :            : 
     232         [ +  - ]:       2831 :         impl_cleanUpDeadItems(m_lComponents, lDeadItems);
     233                 :            : 
     234                 :            :         // a) non free numbers ... return INVALID_NUMBER
     235         [ -  + ]:       2831 :         if (lPossibleNumbers.size () < 1)
     236                 :          0 :             return css::frame::UntitledNumbersConst::INVALID_NUMBER;
     237                 :            : 
     238                 :            :         // b) return first free number
     239 [ +  - ][ +  - ]:       2831 :         return *(lPossibleNumbers.begin ());
     240                 :            : 
     241                 :            :     // <- SYNCHRONIZED
     242                 :            : }
     243                 :            : 
     244                 :       3931 : void NumberedCollection::impl_cleanUpDeadItems (      TNumberedItemHash& lItems    ,
     245                 :            :                                                 const TDeadItemList&     lDeadItems)
     246                 :            : {
     247                 :       3931 :     TDeadItemList::const_iterator pIt;
     248                 :            : 
     249   [ #  #  +  - ]:       7862 :     for (  pIt  = lDeadItems.begin ();
                 [ -  + ]
     250                 :       3931 :            pIt != lDeadItems.end   ();
     251                 :            :          ++pIt                       )
     252                 :            :     {
     253         [ #  # ]:          0 :         const long& rDeadItem = *pIt;
     254         [ #  # ]:          0 :         lItems.erase(rDeadItem);
     255                 :            :     }
     256                 :       3931 : }
     257                 :            : 
     258                 :            : } // namespace comphelper
     259                 :            : 
     260                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10