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() && m_nPos < m_xAccess->getCount())
192 		aRes = m_xAccess->getByIndex(m_nPos++);
193 
194 	if (m_xAccess.is() && m_nPos >= m_xAccess->getCount())
195 	{
196 		impl_stopDisposeListening();
197 		m_xAccess.clear();
198 	}
199 
200 	if (!aRes.hasValue())		// es gibt kein Element mehr
201 		throw starcontainer::NoSuchElementException();
202 	return aRes;
203 }
204 
205 //------------------------------------------------------------------------------
disposing(const starlang::EventObject & aEvent)206 void SAL_CALL OEnumerationByIndex::disposing(const starlang::EventObject& aEvent)
207 		throw(staruno::RuntimeException)
208 {
209 	::osl::ResettableMutexGuard aLock(m_aLock);
210 
211 	if (aEvent.Source == m_xAccess)
212 		m_xAccess.clear();
213 }
214 
215 //------------------------------------------------------------------------------
impl_startDisposeListening()216 void OEnumerationByIndex::impl_startDisposeListening()
217 {
218 	::osl::ResettableMutexGuard aLock(m_aLock);
219 
220 	if (m_bListening)
221 		return;
222 
223 	++m_refCount;
224 	staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
225 	if (xDisposable.is())
226 	{
227 		xDisposable->addEventListener(this);
228 		m_bListening = sal_True;
229 	}
230 	--m_refCount;
231 }
232 
233 //------------------------------------------------------------------------------
impl_stopDisposeListening()234 void OEnumerationByIndex::impl_stopDisposeListening()
235 {
236 	::osl::ResettableMutexGuard aLock(m_aLock);
237 
238 	if (!m_bListening)
239 		return;
240 
241 	++m_refCount;
242 	staruno::Reference< starlang::XComponent > xDisposable(m_xAccess, staruno::UNO_QUERY);
243 	if (xDisposable.is())
244 	{
245 		xDisposable->removeEventListener(this);
246 		m_bListening = sal_False;
247 	}
248 	--m_refCount;
249 }
250 
251 //==================================================================
252 //= OAnyEnumeration
253 //==================================================================
254 
255 //------------------------------------------------------------------------------
OAnyEnumeration(const staruno::Sequence<staruno::Any> & lItems)256 OAnyEnumeration::OAnyEnumeration(const staruno::Sequence< staruno::Any >& lItems)
257 	:m_nPos(0)
258 	,m_lItems(lItems)
259 {
260 }
261 
262 //------------------------------------------------------------------------------
~OAnyEnumeration()263 OAnyEnumeration::~OAnyEnumeration()
264 {
265 }
266 
267 //------------------------------------------------------------------------------
hasMoreElements()268 sal_Bool SAL_CALL OAnyEnumeration::hasMoreElements(  ) throw(staruno::RuntimeException)
269 {
270 	::osl::ResettableMutexGuard aLock(m_aLock);
271 
272 	return (m_lItems.getLength() > m_nPos);
273 }
274 
275 //------------------------------------------------------------------------------
nextElement()276 staruno::Any SAL_CALL OAnyEnumeration::nextElement(  )
277 		throw(starcontainer::NoSuchElementException, starlang::WrappedTargetException, staruno::RuntimeException)
278 {
279 	if ( ! hasMoreElements())
280 		throw starcontainer::NoSuchElementException();
281 
282 	::osl::ResettableMutexGuard aLock(m_aLock);
283 	sal_Int32 nPos = m_nPos;
284 	++m_nPos;
285 	return m_lItems[nPos];
286 }
287 
288 //.........................................................................
289 }	// namespace comphelper
290 //.........................................................................
291