1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_unotools.hxx"
30 
31 
32 #include "unotools/accessiblestatesethelper.hxx"
33 #include <rtl/uuid.h>
34 #include <tools/debug.hxx>
35 
36 #if 0
37 #include <bitset>
38 #endif
39 
40 // defines how many states the bitfield can contain
41 // it has the size of 64 because I use a uInt64
42 #define BITFIELDSIZE 64
43 
44 using namespace	::utl;
45 using namespace	::rtl;
46 using namespace	::com::sun::star;
47 using namespace	::com::sun::star::accessibility;
48 
49 class AccessibleStateSetHelperImpl
50 {
51 public:
52 	AccessibleStateSetHelperImpl();
53 	AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl);
54 	~AccessibleStateSetHelperImpl();
55 
56 	sal_Bool IsEmpty ()
57 		throw (uno::RuntimeException);
58 	sal_Bool Contains (sal_Int16 aState)
59 		throw (uno::RuntimeException);
60     uno::Sequence<sal_Int16> GetStates()
61         throw (uno::RuntimeException);
62 	void AddState(sal_Int16 aState)
63 		throw (uno::RuntimeException);
64 	void RemoveState(sal_Int16 aState)
65 		throw (uno::RuntimeException);
66 	sal_Bool Compare(const AccessibleStateSetHelperImpl* pComparativeValue,
67 						AccessibleStateSetHelperImpl* pOldStates,
68 						AccessibleStateSetHelperImpl* pNewStates)
69 		throw (uno::RuntimeException);
70 
71 	inline void	AddStates( const sal_Int64 _nStates ) SAL_THROW( ( ) );
72 
73 private:
74 #if 0
75 	::std::bitset<BITFIELDSIZE> maStates; //Bitfield
76 #endif
77 	sal_uInt64 maStates;
78 };
79 
80 AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl()
81 	: maStates(0)
82 {
83 }
84 
85 AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl)
86 	: maStates(rImpl.maStates)
87 {
88 }
89 
90 AccessibleStateSetHelperImpl::~AccessibleStateSetHelperImpl()
91 {
92 }
93 
94 inline sal_Bool AccessibleStateSetHelperImpl::IsEmpty ()
95 	throw (uno::RuntimeException)
96 {
97 #if 0
98 	return maStates.none();
99 #endif
100 	return maStates == 0;
101 }
102 
103 inline sal_Bool AccessibleStateSetHelperImpl::Contains (sal_Int16 aState)
104 	throw (uno::RuntimeException)
105 {
106 	DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
107 #if 0
108 	return maStates.test(aState);
109 #endif
110 	sal_uInt64 aTempBitSet(1);
111 	aTempBitSet <<= aState;
112 	return ((aTempBitSet & maStates) != 0);
113 }
114 
115 inline uno::Sequence<sal_Int16> AccessibleStateSetHelperImpl::GetStates()
116     throw (uno::RuntimeException)
117 {
118     uno::Sequence<sal_Int16> aRet(BITFIELDSIZE);
119     sal_Int16* pSeq = aRet.getArray();
120     sal_Int16 nStateCount(0);
121     for (sal_Int16 i = 0; i < BITFIELDSIZE; ++i)
122         if (Contains(i))
123         {
124             *pSeq = i;
125             ++pSeq;
126             ++nStateCount;
127         }
128     aRet.realloc(nStateCount);
129     return aRet;
130 }
131 
132 inline void AccessibleStateSetHelperImpl::AddStates( const sal_Int64 _nStates ) SAL_THROW( ( ) )
133 {
134 	maStates |= _nStates;
135 }
136 
137 inline void AccessibleStateSetHelperImpl::AddState(sal_Int16 aState)
138 	throw (uno::RuntimeException)
139 {
140 	DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
141 #if 0
142 	maStates.set(aState);
143 #endif
144 	sal_uInt64 aTempBitSet(1);
145 	aTempBitSet <<= aState;
146 	maStates |= aTempBitSet;
147 }
148 
149 inline void AccessibleStateSetHelperImpl::RemoveState(sal_Int16 aState)
150 	throw (uno::RuntimeException)
151 {
152 	DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
153 #if 0
154 	maStates.set(aState, 0);
155 #endif
156 	sal_uInt64 aTempBitSet(1);
157 	aTempBitSet <<= aState;
158 	aTempBitSet = ~aTempBitSet;
159 	maStates &= aTempBitSet;
160 }
161 
162 inline sal_Bool AccessibleStateSetHelperImpl::Compare(
163 	const AccessibleStateSetHelperImpl* pComparativeValue,
164 		AccessibleStateSetHelperImpl* pOldStates,
165 		AccessibleStateSetHelperImpl* pNewStates)
166 	throw (uno::RuntimeException)
167 {
168 	sal_Bool bResult(sal_False);
169 	if (pComparativeValue && pOldStates && pNewStates)
170 	{
171 		if (maStates == pComparativeValue->maStates)
172 			bResult = sal_True;
173 		else
174 		{
175 #if 0
176 			std::bitset<BITFIELDSIZE> aTempBitSet(maStates);
177 #endif
178 			sal_uInt64 aTempBitSet(maStates);
179 			aTempBitSet ^= pComparativeValue->maStates;
180 			pOldStates->maStates = aTempBitSet;
181 			pOldStates->maStates &= maStates;
182 			pNewStates->maStates = aTempBitSet;
183 			pNewStates->maStates &= pComparativeValue->maStates;
184 		}
185 	}
186 	return bResult;
187 }
188 
189 
190 //=====  internal  ============================================================
191 
192 AccessibleStateSetHelper::AccessibleStateSetHelper ()
193 	: mpHelperImpl(NULL)
194 {
195 	mpHelperImpl = new AccessibleStateSetHelperImpl();
196 }
197 
198 AccessibleStateSetHelper::AccessibleStateSetHelper ( const sal_Int64 _nInitialStates )
199 	: mpHelperImpl(NULL)
200 {
201 	mpHelperImpl = new AccessibleStateSetHelperImpl();
202 	mpHelperImpl->AddStates( _nInitialStates );
203 }
204 
205 AccessibleStateSetHelper::AccessibleStateSetHelper (const AccessibleStateSetHelper& rHelper)
206 	: cppu::WeakImplHelper1<XAccessibleStateSet>()
207     , mpHelperImpl(NULL)
208 {
209 	if (rHelper.mpHelperImpl)
210 		mpHelperImpl = new AccessibleStateSetHelperImpl(*rHelper.mpHelperImpl);
211 	else
212 		mpHelperImpl = new AccessibleStateSetHelperImpl();
213 }
214 
215 AccessibleStateSetHelper::~AccessibleStateSetHelper(void)
216 {
217 	delete mpHelperImpl;
218 }
219 
220 //=====  XAccessibleStateSet  ==============================================
221 
222     /** Checks whether the current state set is empty.
223 
224         @return
225             Returns <TRUE/> if there is no state in this state set and
226             <FALSE/> if there is at least one state set in it.
227     */
228 sal_Bool SAL_CALL AccessibleStateSetHelper::isEmpty ()
229 	throw (uno::RuntimeException)
230 {
231     ::vos::OGuard aGuard (maMutex);
232 	return mpHelperImpl->IsEmpty();
233 }
234 
235     /** Checks if the given state is a member of the state set of this
236         object.
237 
238         @param aState
239             The state for which to check membership.  This has to be one of
240             the constants of <type>AccessibleStateType</type>.
241 
242         @return
243             Returns <TRUE/> if the given state is a memeber of this object's
244             state set and <FALSE/> otherwise.
245     */
246 sal_Bool SAL_CALL AccessibleStateSetHelper::contains (sal_Int16 aState)
247 	throw (uno::RuntimeException)
248 {
249     ::vos::OGuard aGuard (maMutex);
250 	return mpHelperImpl->Contains(aState);
251 }
252 
253     /** Checks if all of the given states are in this object's state
254         set.
255 
256         @param aStateSet
257             This sequence of states is interpreted as set and every of its
258             members, duplicates are ignored, is checked for membership in
259             this object's state set.  Each state has to be one of the
260             constants of <type>AccessibleStateType</type>.
261 
262         @return
263             Returns <TRUE/> if all states of the given state set are members
264             of this object's state set.  <FALSE/> is returned if at least
265             one of the states in the given state is not a member of this
266             object's state set.
267     */
268 sal_Bool SAL_CALL AccessibleStateSetHelper::containsAll
269 	(const uno::Sequence<sal_Int16>& rStateSet)
270 	throw (uno::RuntimeException)
271 {
272     ::vos::OGuard aGuard (maMutex);
273 	sal_Int32 nCount(rStateSet.getLength());
274 	const sal_Int16* pStates = rStateSet.getConstArray();
275 	sal_Int32 i = 0;
276 	sal_Bool bFound(sal_True);
277 	while (i < nCount)
278 	{
279 		bFound = mpHelperImpl->Contains(pStates[i]);
280 		i++;
281 	}
282 	return bFound;
283 }
284 
285 uno::Sequence<sal_Int16> SAL_CALL AccessibleStateSetHelper::getStates()
286     throw (uno::RuntimeException)
287 {
288     ::vos::OGuard aGuard(maMutex);
289     return mpHelperImpl->GetStates();
290 }
291 
292 void AccessibleStateSetHelper::AddState(sal_Int16 aState)
293 	throw (uno::RuntimeException)
294 {
295     ::vos::OGuard aGuard (maMutex);
296 	mpHelperImpl->AddState(aState);
297 }
298 
299 void AccessibleStateSetHelper::RemoveState(sal_Int16 aState)
300 	throw (uno::RuntimeException)
301 {
302     ::vos::OGuard aGuard (maMutex);
303 	mpHelperImpl->RemoveState(aState);
304 }
305 
306 sal_Bool AccessibleStateSetHelper::Compare(
307 	const AccessibleStateSetHelper& rComparativeValue,
308 		AccessibleStateSetHelper& rOldStates,
309 		AccessibleStateSetHelper& rNewStates)
310 	throw (uno::RuntimeException)
311 {
312     ::vos::OGuard aGuard (maMutex);
313 	return mpHelperImpl->Compare(rComparativeValue.mpHelperImpl,
314 		rOldStates.mpHelperImpl, rNewStates.mpHelperImpl);
315 }
316 
317 //=====  XTypeProvider  =======================================================
318 
319 uno::Sequence< ::com::sun::star::uno::Type>
320 	AccessibleStateSetHelper::getTypes (void)
321     throw (::com::sun::star::uno::RuntimeException)
322 {
323 	const ::com::sun::star::uno::Type aTypeList[] = {
324     	::getCppuType((const uno::Reference<
325         	XAccessibleStateSet>*)0),
326     	::getCppuType((const uno::Reference<
327         	lang::XTypeProvider>*)0)
328 		};
329 	::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type>
330     	aTypeSequence (aTypeList, 2);
331 	return aTypeSequence;
332 }
333 
334 uno::Sequence<sal_Int8> SAL_CALL
335 	AccessibleStateSetHelper::getImplementationId (void)
336     throw (::com::sun::star::uno::RuntimeException)
337 {
338     ::vos::OGuard aGuard (maMutex);
339 	static uno::Sequence<sal_Int8> aId;
340 	if (aId.getLength() == 0)
341 	{
342 		aId.realloc (16);
343 		rtl_createUuid ((sal_uInt8 *)aId.getArray(), 0, sal_True);
344 	}
345 	return aId;
346 }
347