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 //------------------------------------------------------------------------------
OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess> & _rxAccess)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 //------------------------------------------------------------------------------
OEnumerationByName(const staruno::Reference<starcontainer::XNameAccess> & _rxAccess,const staruno::Sequence<::rtl::OUString> & _aNames)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 //------------------------------------------------------------------------------
~OEnumerationByName()59 OEnumerationByName::~OEnumerationByName()
60 {
61     impl_stopDisposeListening();
62 }
63 
64 //------------------------------------------------------------------------------
hasMoreElements()65 sal_Bool SAL_CALL OEnumerationByName::hasMoreElements(  ) throw(staruno::RuntimeException)
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 //------------------------------------------------------------------------------
nextElement()82 staruno::Any SAL_CALL OEnumerationByName::nextElement(  )
83 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
84 {
85     ::osl::ResettableMutexGuard aLock(m_aLock);
86 
87 	staruno::Any aRes;
88 	if (m_xAccess.is() && m_nPos < m_aNames.getLength())
89 		aRes = m_xAccess->getByName(m_aNames.getConstArray()[m_nPos++]);
90 
91 	if (m_xAccess.is() && m_nPos >= m_aNames.getLength())
92     {
93         impl_stopDisposeListening();
94         m_xAccess.clear();
95     }
96 
97 	if (!aRes.hasValue())		// es gibt kein Element mehr
98 		throw starcontainer::NoSuchElementException();
99 
100 	return aRes;
101 }
102 
103 //------------------------------------------------------------------------------
disposing(const starlang::EventObject & aEvent)104 void SAL_CALL OEnumerationByName::disposing(const starlang::EventObject& aEvent)
105         throw(staruno::RuntimeException)
106 {
107     ::osl::ResettableMutexGuard aLock(m_aLock);
108 
109     if (aEvent.Source == m_xAccess)
110         m_xAccess.clear();
111 }
112 
113 //------------------------------------------------------------------------------
impl_startDisposeListening()114 void OEnumerationByName::impl_startDisposeListening()
115 {
116     ::osl::ResettableMutexGuard aLock(m_aLock);
117 
118     if (m_bListening)
119         return;
120 
121     ++m_refCount;
122     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
123     if (xDisposable.is())
124     {
125         xDisposable->addEventListener(this);
126         m_bListening = sal_True;
127     }
128     --m_refCount;
129 }
130 
131 //------------------------------------------------------------------------------
impl_stopDisposeListening()132 void OEnumerationByName::impl_stopDisposeListening()
133 {
134     ::osl::ResettableMutexGuard aLock(m_aLock);
135 
136     if (!m_bListening)
137         return;
138 
139     ++m_refCount;
140     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
141     if (xDisposable.is())
142     {
143         xDisposable->removeEventListener(this);
144         m_bListening = sal_False;
145     }
146     --m_refCount;
147 }
148 
149 //==================================================================
150 //= OEnumerationByIndex
151 //==================================================================
152 //------------------------------------------------------------------------------
OEnumerationByIndex(const staruno::Reference<starcontainer::XIndexAccess> & _rxAccess)153 OEnumerationByIndex::OEnumerationByIndex(const staruno::Reference< starcontainer::XIndexAccess >& _rxAccess)
154     :m_nPos(0)
155     ,m_xAccess(_rxAccess)
156     ,m_bListening(sal_False)
157 {
158     impl_startDisposeListening();
159 }
160 
161 //------------------------------------------------------------------------------
~OEnumerationByIndex()162 OEnumerationByIndex::~OEnumerationByIndex()
163 {
164     impl_stopDisposeListening();
165 }
166 
167 //------------------------------------------------------------------------------
hasMoreElements()168 sal_Bool SAL_CALL OEnumerationByIndex::hasMoreElements(  ) throw(staruno::RuntimeException)
169 {
170     ::osl::ResettableMutexGuard aLock(m_aLock);
171 
172 	if (m_xAccess.is() && m_xAccess->getCount() > m_nPos)
173         return sal_True;
174 
175     if (m_xAccess.is())
176     {
177         impl_stopDisposeListening();
178         m_xAccess.clear();
179     }
180 
181     return sal_False;
182 }
183 
184 //------------------------------------------------------------------------------
nextElement()185 staruno::Any SAL_CALL OEnumerationByIndex::nextElement(  )
186 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
187 {
188     ::osl::ResettableMutexGuard aLock(m_aLock);
189 
190 	staruno::Any aRes;
191 	if (m_xAccess.is())
192 	{
193 		aRes = m_xAccess->getByIndex(m_nPos++);
194 		if (m_nPos >= m_xAccess->getCount())
195         {
196             impl_stopDisposeListening();
197             m_xAccess.clear();
198         }
199 	}
200 
201 	if (!aRes.hasValue())		// es gibt kein Element mehr
202 		throw starcontainer::NoSuchElementException();
203 	return aRes;
204 }
205 
206 //------------------------------------------------------------------------------
disposing(const starlang::EventObject & aEvent)207 void SAL_CALL OEnumerationByIndex::disposing(const starlang::EventObject& aEvent)
208         throw(staruno::RuntimeException)
209 {
210     ::osl::ResettableMutexGuard aLock(m_aLock);
211 
212     if (aEvent.Source == m_xAccess)
213         m_xAccess.clear();
214 }
215 
216 //------------------------------------------------------------------------------
impl_startDisposeListening()217 void OEnumerationByIndex::impl_startDisposeListening()
218 {
219     ::osl::ResettableMutexGuard aLock(m_aLock);
220 
221     if (m_bListening)
222         return;
223 
224     ++m_refCount;
225     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
226     if (xDisposable.is())
227     {
228         xDisposable->addEventListener(this);
229         m_bListening = sal_True;
230     }
231     --m_refCount;
232 }
233 
234 //------------------------------------------------------------------------------
impl_stopDisposeListening()235 void OEnumerationByIndex::impl_stopDisposeListening()
236 {
237     ::osl::ResettableMutexGuard aLock(m_aLock);
238 
239     if (!m_bListening)
240         return;
241 
242     ++m_refCount;
243     staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
244     if (xDisposable.is())
245     {
246         xDisposable->removeEventListener(this);
247         m_bListening = sal_False;
248     }
249     --m_refCount;
250 }
251 
252 //==================================================================
253 //= OAnyEnumeration
254 //==================================================================
255 
256 //------------------------------------------------------------------------------
OAnyEnumeration(const staruno::Sequence<staruno::Any> & lItems)257 OAnyEnumeration::OAnyEnumeration(const staruno::Sequence< staruno::Any >& lItems)
258     :m_nPos(0)
259     ,m_lItems(lItems)
260 {
261 }
262 
263 //------------------------------------------------------------------------------
~OAnyEnumeration()264 OAnyEnumeration::~OAnyEnumeration()
265 {
266 }
267 
268 //------------------------------------------------------------------------------
hasMoreElements()269 sal_Bool SAL_CALL OAnyEnumeration::hasMoreElements(  ) throw(staruno::RuntimeException)
270 {
271     ::osl::ResettableMutexGuard aLock(m_aLock);
272 
273 	return (m_lItems.getLength() > m_nPos);
274 }
275 
276 //------------------------------------------------------------------------------
nextElement()277 staruno::Any SAL_CALL OAnyEnumeration::nextElement(  )
278 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
279 {
280 	if ( ! hasMoreElements())
281 		throw starcontainer::NoSuchElementException();
282 
283     ::osl::ResettableMutexGuard aLock(m_aLock);
284     sal_Int32 nPos = m_nPos;
285     ++m_nPos;
286     return m_lItems[nPos];
287 }
288 
289 //.........................................................................
290 }	// namespace comphelper
291 //.........................................................................
292 
293 
294