LCOV - code coverage report
Current view: top level - comphelper/source/misc - numberedcollection.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 72 92 78.3 %
Date: 2015-06-13 12:38:46 Functions: 10 11 90.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <algorithm>
      21             : #include <comphelper/numberedcollection.hxx>
      22             : #include <com/sun/star/frame/UntitledNumbersConst.hpp>
      23             : 
      24             : namespace comphelper{
      25             : 
      26             : static const char ERRMSG_INVALID_COMPONENT_PARAM[] = "NULL as component reference not allowed.";
      27             : 
      28             : 
      29        3467 : NumberedCollection::NumberedCollection()
      30             :     : ::cppu::BaseMutex ()
      31             :     , m_sUntitledPrefix ()
      32             :     , m_lComponents     ()
      33        3467 :     , m_xOwner          ()
      34             : {
      35        3467 : }
      36             : 
      37             : 
      38        6768 : NumberedCollection::~NumberedCollection()
      39             : {
      40        6768 : }
      41             : 
      42             : 
      43        3467 : void NumberedCollection::setOwner(const css::uno::Reference< css::uno::XInterface >& xOwner)
      44             : {
      45             :     // SYNCHRONIZED ->
      46        3467 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
      47             : 
      48        3467 :         m_xOwner = xOwner;
      49             : 
      50             :     // <- SYNCHRONIZED
      51        3467 : }
      52             : 
      53             : 
      54        3460 : void NumberedCollection::setUntitledPrefix(const OUString& sPrefix)
      55             : {
      56             :     // SYNCHRONIZED ->
      57        3460 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
      58             : 
      59        3460 :         m_sUntitledPrefix = sPrefix;
      60             : 
      61             :     // <- SYNCHRONIZED
      62        3460 : }
      63             : 
      64             : 
      65        4378 : ::sal_Int32 SAL_CALL NumberedCollection::leaseNumber(const css::uno::Reference< css::uno::XInterface >& xComponent)
      66             :     throw (css::lang::IllegalArgumentException,
      67             :            css::uno::RuntimeException, std::exception         )
      68             : {
      69             :     // SYNCHRONIZED ->
      70        4378 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
      71             : 
      72        4378 :         if ( ! xComponent.is ())
      73           0 :             throw css::lang::IllegalArgumentException (OUString(ERRMSG_INVALID_COMPONENT_PARAM), m_xOwner.get(), 1);
      74             : 
      75        4378 :         sal_IntPtr pComponent = reinterpret_cast<sal_IntPtr>( xComponent.get() );
      76        4378 :         TNumberedItemHash::const_iterator pIt = m_lComponents.find (pComponent);
      77             : 
      78             :         // a) component already exists - return it's number directly
      79        4378 :         if (pIt != m_lComponents.end())
      80           0 :             return pIt->second.nNumber;
      81             : 
      82             :         // b) component must be added new to this container
      83             : 
      84             :         // b1) collection is full - no further components possible
      85             :         //     -> return INVALID_NUMBER
      86        4378 :         ::sal_Int32 nFreeNumber = impl_searchFreeNumber();
      87        4378 :         if (nFreeNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER)
      88           0 :             return css::frame::UntitledNumbersConst::INVALID_NUMBER;
      89             : 
      90             :         // b2) add component to collection and return its number
      91        8756 :         TNumberedItem aItem;
      92        4378 :         aItem.xItem   = css::uno::WeakReference< css::uno::XInterface >(xComponent);
      93        4378 :         aItem.nNumber = nFreeNumber;
      94        4378 :         m_lComponents[pComponent] = aItem;
      95             : 
      96        8756 :         return nFreeNumber;
      97             : 
      98             :     // <- SYNCHRONIZED
      99             : }
     100             : 
     101             : 
     102        1103 : void SAL_CALL NumberedCollection::releaseNumber(::sal_Int32 nNumber)
     103             :     throw (css::lang::IllegalArgumentException,
     104             :            css::uno::RuntimeException, std::exception         )
     105             : {
     106             :     // SYNCHRONIZED ->
     107        1103 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     108             : 
     109        1103 :     if (nNumber == css::frame::UntitledNumbersConst::INVALID_NUMBER)
     110           0 :         throw css::lang::IllegalArgumentException ("Special valkud INVALID_NUMBER not allowed as input parameter.", m_xOwner.get(), 1);
     111             : 
     112        2206 :     TDeadItemList               lDeadItems;
     113        1103 :     TNumberedItemHash::iterator pComponent;
     114             : 
     115        4008 :     for (  pComponent  = m_lComponents.begin ();
     116        2672 :            pComponent != m_lComponents.end   ();
     117             :          ++pComponent                          )
     118             :     {
     119        1336 :         const TNumberedItem&                              rItem = pComponent->second;
     120        1336 :         const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get();
     121             : 
     122        1336 :         if ( ! xItem.is ())
     123             :         {
     124           0 :             lDeadItems.push_back(pComponent->first);
     125           0 :             continue;
     126             :         }
     127             : 
     128        1336 :         if (rItem.nNumber == nNumber)
     129             :         {
     130        1103 :             m_lComponents.erase (pComponent);
     131        1103 :             break;
     132             :         }
     133         233 :     }
     134             : 
     135        2206 :     impl_cleanUpDeadItems(m_lComponents, lDeadItems);
     136             : 
     137             :     // <- SYNCHRONIZED
     138        1103 : }
     139             : 
     140             : 
     141           0 : void SAL_CALL NumberedCollection::releaseNumberForComponent(const css::uno::Reference< css::uno::XInterface >& xComponent)
     142             :     throw (css::lang::IllegalArgumentException,
     143             :            css::uno::RuntimeException, std::exception         )
     144             : {
     145             :     // SYNCHRONIZED ->
     146           0 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     147             : 
     148           0 :         if ( ! xComponent.is ())
     149           0 :             throw css::lang::IllegalArgumentException (OUString(ERRMSG_INVALID_COMPONENT_PARAM), m_xOwner.get(), 1);
     150             : 
     151           0 :         sal_IntPtr pComponent = reinterpret_cast<sal_IntPtr>( xComponent.get() );
     152           0 :         TNumberedItemHash::iterator pIt = m_lComponents.find (pComponent);
     153             : 
     154             :         // a) component exists and will be removed
     155           0 :         if (pIt != m_lComponents.end())
     156           0 :             m_lComponents.erase(pIt);
     157             : 
     158             :         // else
     159             :         // b) component does not exists - nothing todo here (ignore request!)
     160             : 
     161             :     // <- SYNCHRONIZED
     162           0 : }
     163             : 
     164             : 
     165        5753 : OUString SAL_CALL NumberedCollection::getUntitledPrefix()
     166             :     throw (css::uno::RuntimeException, std::exception)
     167             : {
     168             :     // SYNCHRONIZED ->
     169        5753 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     170             : 
     171        5753 :         return m_sUntitledPrefix;
     172             : 
     173             :     // <- SYNCHRONIZED
     174             : }
     175             : 
     176             : 
     177             : /** create an ordered list of all possible numbers ...
     178             :     e.g. {1,2,3,...,N} Max size of these list will be
     179             :     current size of component list + 1 .
     180             : 
     181             :     "+1" ... because in case all numbers in range 1..n
     182             :     are in use we need a new number n+1 :-)
     183             : 
     184             :     Every item which is already used as unique number
     185             :     will be removed. At the end a list of e.g. {3,6,...,M}
     186             :     exists where the first item represent the lowest free
     187             :     number (in this example 3).
     188             :  */
     189        4378 : ::sal_Int32 NumberedCollection::impl_searchFreeNumber ()
     190             : {
     191             :     // create ordered list of all possible numbers.
     192        4378 :     ::std::vector< ::sal_Int32 > lPossibleNumbers;
     193        4378 :     ::sal_Int32                  c = (::sal_Int32)m_lComponents.size ();
     194        4378 :     ::sal_Int32                  i = 1;
     195             : 
     196             :     // c can't be less then 0 ... otherwise hash.size() has an error :-)
     197             :     // But we need at least n+1 numbers here.
     198        4378 :     c += 1;
     199             : 
     200        9966 :     for (i=1; i<=c; ++i)
     201        5588 :         lPossibleNumbers.push_back (i);
     202             : 
     203             :     // SYNCHRONIZED ->
     204        8756 :     ::osl::ResettableMutexGuard aLock(m_aMutex);
     205             : 
     206        8756 :         TDeadItemList                     lDeadItems;
     207        4378 :         TNumberedItemHash::const_iterator pComponent;
     208             : 
     209       16764 :         for (  pComponent  = m_lComponents.begin ();
     210       11176 :                pComponent != m_lComponents.end   ();
     211             :              ++pComponent                          )
     212             :         {
     213        1210 :             const TNumberedItem&                              rItem = pComponent->second;
     214        1210 :             const css::uno::Reference< css::uno::XInterface > xItem = rItem.xItem.get();
     215             : 
     216        1210 :             if ( ! xItem.is ())
     217             :             {
     218           0 :                 lDeadItems.push_back(pComponent->first);
     219           0 :                 continue;
     220             :             }
     221             : 
     222        1210 :             ::std::vector< ::sal_Int32 >::iterator pPossible = ::std::find(lPossibleNumbers.begin (), lPossibleNumbers.end (), rItem.nNumber);
     223        1210 :             if (pPossible != lPossibleNumbers.end ())
     224        1210 :                 lPossibleNumbers.erase (pPossible);
     225        1210 :         }
     226             : 
     227        4378 :         impl_cleanUpDeadItems(m_lComponents, lDeadItems);
     228             : 
     229             :         // a) non free numbers ... return INVALID_NUMBER
     230        4378 :         if (lPossibleNumbers.size () < 1)
     231           0 :             return css::frame::UntitledNumbersConst::INVALID_NUMBER;
     232             : 
     233             :         // b) return first free number
     234        8756 :         return *(lPossibleNumbers.begin ());
     235             : 
     236             :     // <- SYNCHRONIZED
     237             : }
     238             : 
     239        5481 : void NumberedCollection::impl_cleanUpDeadItems (      TNumberedItemHash& lItems    ,
     240             :                                                 const TDeadItemList&     lDeadItems)
     241             : {
     242        5481 :     TDeadItemList::const_iterator pIt;
     243             : 
     244       16443 :     for (  pIt  = lDeadItems.begin ();
     245       10962 :            pIt != lDeadItems.end   ();
     246             :          ++pIt                       )
     247             :     {
     248           0 :         const long& rDeadItem = *pIt;
     249           0 :         lItems.erase(rDeadItem);
     250             :     }
     251        5481 : }
     252             : 
     253             : } // namespace comphelper
     254             : 
     255             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11