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