xref: /trunk/main/comphelper/source/container/enumhelper.cxx (revision 9d37da743abb7db0a497688391f6e55a19f27c44)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_comphelper.hxx"
26 #include <comphelper/enumhelper.hxx>
27 #include <com/sun/star/lang/XComponent.hpp>
28 
29 //.........................................................................
30 namespace comphelper
31 {
32 //.........................................................................
33 
34 //==================================================================
35 //= OEnumerationByName
36 //==================================================================
37 //------------------------------------------------------------------------------
38 OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess)
39     :m_aNames(_rxAccess->getElementNames())
40     ,m_nPos(0)
41     ,m_xAccess(_rxAccess)
42     ,m_bListening(sal_False)
43 {
44     impl_startDisposeListening();
45 }
46 
47 //------------------------------------------------------------------------------
48 OEnumerationByName::OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess>& _rxAccess,
49                                        const staruno::Sequence< ::rtl::OUString >&           _aNames  )
50     :m_aNames(_aNames)
51     ,m_nPos(0)
52     ,m_xAccess(_rxAccess)
53     ,m_bListening(sal_False)
54 {
55     impl_startDisposeListening();
56 }
57 
58 //------------------------------------------------------------------------------
59 OEnumerationByName::~OEnumerationByName()
60 {
61     impl_stopDisposeListening();
62 }
63 
64 //------------------------------------------------------------------------------
65 sal_Bool SAL_CALL OEnumerationByName::hasMoreElements(  )
66 {
67     ::osl::ResettableMutexGuard aLock(m_aLock);
68 
69     if (m_xAccess.is() && m_aNames.getLength() > m_nPos)
70         return sal_True;
71 
72     if (m_xAccess.is())
73     {
74         impl_stopDisposeListening();
75         m_xAccess.clear();
76     }
77 
78     return sal_False;
79 }
80 
81 //------------------------------------------------------------------------------
82 staruno::Any SAL_CALL OEnumerationByName::nextElement(  )
83 {
84     ::osl::ResettableMutexGuard aLock(m_aLock);
85 
86     staruno::Any aRes;
87     if (m_xAccess.is() && m_nPos < m_aNames.getLength())
88         aRes = m_xAccess->getByName(m_aNames.getConstArray()[m_nPos++]);
89 
90     if (m_xAccess.is() && m_nPos >= m_aNames.getLength())
91     {
92         impl_stopDisposeListening();
93         m_xAccess.clear();
94     }
95 
96     if (!aRes.hasValue())       // es gibt kein Element mehr
97         throw starcontainer::NoSuchElementException();
98 
99     return aRes;
100 }
101 
102 //------------------------------------------------------------------------------
103 void SAL_CALL OEnumerationByName::disposing(const starlang::EventObject& aEvent)
104 {
105     ::osl::ResettableMutexGuard aLock(m_aLock);
106 
107     if (aEvent.Source == m_xAccess)
108         m_xAccess.clear();
109 }
110 
111 //------------------------------------------------------------------------------
112 void OEnumerationByName::impl_startDisposeListening()
113 {
114     ::osl::ResettableMutexGuard aLock(m_aLock);
115 
116     if (m_bListening)
117         return;
118 
119     ++m_refCount;
120     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
121     if (xDisposable.is())
122     {
123         xDisposable->addEventListener(this);
124         m_bListening = sal_True;
125     }
126     --m_refCount;
127 }
128 
129 //------------------------------------------------------------------------------
130 void OEnumerationByName::impl_stopDisposeListening()
131 {
132     ::osl::ResettableMutexGuard aLock(m_aLock);
133 
134     if (!m_bListening)
135         return;
136 
137     ++m_refCount;
138     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
139     if (xDisposable.is())
140     {
141         xDisposable->removeEventListener(this);
142         m_bListening = sal_False;
143     }
144     --m_refCount;
145 }
146 
147 //==================================================================
148 //= OEnumerationByIndex
149 //==================================================================
150 //------------------------------------------------------------------------------
151 OEnumerationByIndex::OEnumerationByIndex(const staruno::Reference< starcontainer::XIndexAccess >& _rxAccess)
152     :m_nPos(0)
153     ,m_xAccess(_rxAccess)
154     ,m_bListening(sal_False)
155 {
156     impl_startDisposeListening();
157 }
158 
159 //------------------------------------------------------------------------------
160 OEnumerationByIndex::~OEnumerationByIndex()
161 {
162     impl_stopDisposeListening();
163 }
164 
165 //------------------------------------------------------------------------------
166 sal_Bool SAL_CALL OEnumerationByIndex::hasMoreElements(  )
167 {
168     ::osl::ResettableMutexGuard aLock(m_aLock);
169 
170     if (m_xAccess.is() && m_xAccess->getCount() > m_nPos)
171         return sal_True;
172 
173     if (m_xAccess.is())
174     {
175         impl_stopDisposeListening();
176         m_xAccess.clear();
177     }
178 
179     return sal_False;
180 }
181 
182 //------------------------------------------------------------------------------
183 staruno::Any SAL_CALL OEnumerationByIndex::nextElement(  )
184 {
185     ::osl::ResettableMutexGuard aLock(m_aLock);
186 
187     staruno::Any aRes;
188     if (m_xAccess.is() && m_nPos < m_xAccess->getCount())
189         aRes = m_xAccess->getByIndex(m_nPos++);
190 
191     if (m_xAccess.is() && m_nPos >= m_xAccess->getCount())
192     {
193         impl_stopDisposeListening();
194         m_xAccess.clear();
195     }
196 
197     if (!aRes.hasValue())       // es gibt kein Element mehr
198         throw starcontainer::NoSuchElementException();
199     return aRes;
200 }
201 
202 //------------------------------------------------------------------------------
203 void SAL_CALL OEnumerationByIndex::disposing(const starlang::EventObject& aEvent)
204 {
205     ::osl::ResettableMutexGuard aLock(m_aLock);
206 
207     if (aEvent.Source == m_xAccess)
208         m_xAccess.clear();
209 }
210 
211 //------------------------------------------------------------------------------
212 void OEnumerationByIndex::impl_startDisposeListening()
213 {
214     ::osl::ResettableMutexGuard aLock(m_aLock);
215 
216     if (m_bListening)
217         return;
218 
219     ++m_refCount;
220     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
221     if (xDisposable.is())
222     {
223         xDisposable->addEventListener(this);
224         m_bListening = sal_True;
225     }
226     --m_refCount;
227 }
228 
229 //------------------------------------------------------------------------------
230 void OEnumerationByIndex::impl_stopDisposeListening()
231 {
232     ::osl::ResettableMutexGuard aLock(m_aLock);
233 
234     if (!m_bListening)
235         return;
236 
237     ++m_refCount;
238     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
239     if (xDisposable.is())
240     {
241         xDisposable->removeEventListener(this);
242         m_bListening = sal_False;
243     }
244     --m_refCount;
245 }
246 
247 //==================================================================
248 //= OAnyEnumeration
249 //==================================================================
250 
251 //------------------------------------------------------------------------------
252 OAnyEnumeration::OAnyEnumeration(const staruno::Sequence< staruno::Any >& lItems)
253     :m_nPos(0)
254     ,m_lItems(lItems)
255 {
256 }
257 
258 //------------------------------------------------------------------------------
259 OAnyEnumeration::~OAnyEnumeration()
260 {
261 }
262 
263 //------------------------------------------------------------------------------
264 sal_Bool SAL_CALL OAnyEnumeration::hasMoreElements(  )
265 {
266     ::osl::ResettableMutexGuard aLock(m_aLock);
267 
268     return (m_lItems.getLength() > m_nPos);
269 }
270 
271 //------------------------------------------------------------------------------
272 staruno::Any SAL_CALL OAnyEnumeration::nextElement(  )
273 {
274     if ( ! hasMoreElements())
275         throw starcontainer::NoSuchElementException();
276 
277     ::osl::ResettableMutexGuard aLock(m_aLock);
278     sal_Int32 nPos = m_nPos;
279     ++m_nPos;
280     return m_lItems[nPos];
281 }
282 
283 //.........................................................................
284 }   // namespace comphelper
285 //.........................................................................
286