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: */
|