1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <unotools/accessiblestatesethelper.hxx>
21 #include <tools/debug.hxx>
22 
23 // defines how many states the bitfield can contain
24 // it has the size of 64 because I use a uInt64
25 #define BITFIELDSIZE 64
26 
27 using namespace ::utl;
28 using namespace ::com::sun::star;
29 using namespace ::com::sun::star::accessibility;
30 
31 class AccessibleStateSetHelperImpl
32 {
33 public:
34     AccessibleStateSetHelperImpl();
35     AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl);
36 
37     /// @throws uno::RuntimeException
38     bool IsEmpty () const;
39     /// @throws uno::RuntimeException
40     bool Contains (sal_Int16 aState) const;
41     /// @throws uno::RuntimeException
42     uno::Sequence<sal_Int16> GetStates() const;
43     /// @throws uno::RuntimeException
44     void AddState(sal_Int16 aState);
45     /// @throws uno::RuntimeException
46     void RemoveState(sal_Int16 aState);
47 
48     inline void AddStates( const sal_Int64 _nStates );
49 
50 private:
51     sal_uInt64 maStates;
52 };
53 
AccessibleStateSetHelperImpl()54 AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl()
55     : maStates(0)
56 {
57 }
58 
AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl & rImpl)59 AccessibleStateSetHelperImpl::AccessibleStateSetHelperImpl(const AccessibleStateSetHelperImpl& rImpl)
60     : maStates(rImpl.maStates)
61 {
62 }
63 
IsEmpty() const64 inline bool AccessibleStateSetHelperImpl::IsEmpty () const
65 {
66     return maStates == 0;
67 }
68 
Contains(sal_Int16 aState) const69 inline bool AccessibleStateSetHelperImpl::Contains (sal_Int16 aState) const
70 {
71     DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
72     sal_uInt64 aTempBitSet(1);
73     aTempBitSet <<= aState;
74     return ((aTempBitSet & maStates) != 0);
75 }
76 
GetStates() const77 inline uno::Sequence<sal_Int16> AccessibleStateSetHelperImpl::GetStates() const
78 {
79     uno::Sequence<sal_Int16> aRet(BITFIELDSIZE);
80     sal_Int16* pSeq = aRet.getArray();
81     sal_Int16 nStateCount(0);
82     for (sal_Int16 i = 0; i < BITFIELDSIZE; ++i)
83         if (Contains(i))
84         {
85             *pSeq = i;
86             ++pSeq;
87             ++nStateCount;
88         }
89     aRet.realloc(nStateCount);
90     return aRet;
91 }
92 
AddStates(const sal_Int64 _nStates)93 inline void AccessibleStateSetHelperImpl::AddStates( const sal_Int64 _nStates )
94 {
95     maStates |= _nStates;
96 }
97 
AddState(sal_Int16 aState)98 inline void AccessibleStateSetHelperImpl::AddState(sal_Int16 aState)
99 {
100     DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
101     sal_uInt64 aTempBitSet(1);
102     aTempBitSet <<= aState;
103     maStates |= aTempBitSet;
104 }
105 
RemoveState(sal_Int16 aState)106 inline void AccessibleStateSetHelperImpl::RemoveState(sal_Int16 aState)
107 {
108     DBG_ASSERT(aState < BITFIELDSIZE, "the statesset is too small");
109     sal_uInt64 aTempBitSet(1);
110     aTempBitSet <<= aState;
111     aTempBitSet = ~aTempBitSet;
112     maStates &= aTempBitSet;
113 }
114 
115 //=====  internal  ============================================================
116 
AccessibleStateSetHelper()117 AccessibleStateSetHelper::AccessibleStateSetHelper ()
118     : mpHelperImpl(new AccessibleStateSetHelperImpl)
119 {
120 }
121 
AccessibleStateSetHelper(const sal_Int64 _nInitialStates)122 AccessibleStateSetHelper::AccessibleStateSetHelper ( const sal_Int64 _nInitialStates )
123     : mpHelperImpl(new AccessibleStateSetHelperImpl)
124 {
125     mpHelperImpl->AddStates( _nInitialStates );
126 }
127 
AccessibleStateSetHelper(const AccessibleStateSetHelper & rHelper)128 AccessibleStateSetHelper::AccessibleStateSetHelper (const AccessibleStateSetHelper& rHelper)
129     : cppu::WeakImplHelper<XAccessibleStateSet>(rHelper)
130 {
131     if (rHelper.mpHelperImpl)
132         mpHelperImpl.reset(new AccessibleStateSetHelperImpl(*rHelper.mpHelperImpl));
133     else
134         mpHelperImpl.reset(new AccessibleStateSetHelperImpl());
135 }
136 
~AccessibleStateSetHelper()137 AccessibleStateSetHelper::~AccessibleStateSetHelper()
138 {
139 }
140 
141 //=====  XAccessibleStateSet  ==============================================
142 
143     /** Checks whether the current state set is empty.
144 
145         @return
146             Returns <TRUE/> if there is no state in this state set and
147             <FALSE/> if there is at least one state set in it.
148     */
isEmpty()149 sal_Bool SAL_CALL AccessibleStateSetHelper::isEmpty ()
150 {
151     osl::MutexGuard aGuard (maMutex);
152     return mpHelperImpl->IsEmpty();
153 }
154 
155     /** Checks if the given state is a member of the state set of this
156         object.
157 
158         @param aState
159             The state for which to check membership.  This has to be one of
160             the constants of <type>AccessibleStateType</type>.
161 
162         @return
163             Returns <TRUE/> if the given state is a member of this object's
164             state set and <FALSE/> otherwise.
165     */
contains(sal_Int16 aState)166 sal_Bool SAL_CALL AccessibleStateSetHelper::contains (sal_Int16 aState)
167 {
168     osl::MutexGuard aGuard (maMutex);
169     return mpHelperImpl->Contains(aState);
170 }
171 
172     /** Checks if all of the given states are in this object's state
173         set.
174 
175         @param aStateSet
176             This sequence of states is interpreted as set and every of its
177             members, duplicates are ignored, is checked for membership in
178             this object's state set.  Each state has to be one of the
179             constants of <type>AccessibleStateType</type>.
180 
181         @return
182             Returns <TRUE/> if all states of the given state set are members
183             of this object's state set.  <FALSE/> is returned if at least
184             one of the states in the given state is not a member of this
185             object's state set.
186     */
containsAll(const uno::Sequence<sal_Int16> & rStateSet)187 sal_Bool SAL_CALL AccessibleStateSetHelper::containsAll
188     (const uno::Sequence<sal_Int16>& rStateSet)
189 {
190     osl::MutexGuard aGuard (maMutex);
191     return std::all_of(rStateSet.begin(), rStateSet.end(),
192         [this](const sal_Int16 nState) { return mpHelperImpl->Contains(nState); });
193 }
194 
getStates()195 uno::Sequence<sal_Int16> SAL_CALL AccessibleStateSetHelper::getStates()
196 {
197     osl::MutexGuard aGuard(maMutex);
198     return mpHelperImpl->GetStates();
199 }
200 
AddState(sal_Int16 aState)201 void AccessibleStateSetHelper::AddState(sal_Int16 aState)
202 {
203     osl::MutexGuard aGuard (maMutex);
204     mpHelperImpl->AddState(aState);
205 }
206 
RemoveState(sal_Int16 aState)207 void AccessibleStateSetHelper::RemoveState(sal_Int16 aState)
208 {
209     osl::MutexGuard aGuard (maMutex);
210     mpHelperImpl->RemoveState(aState);
211 }
212 
213 //=====  XTypeProvider  =======================================================
214 
getTypes()215 uno::Sequence< css::uno::Type> AccessibleStateSetHelper::getTypes()
216 {
217     css::uno::Sequence< css::uno::Type> aTypeSequence {
218         cppu::UnoType<XAccessibleStateSet>::get(),
219         cppu::UnoType<lang::XTypeProvider>::get()
220     };
221     return aTypeSequence;
222 }
223 
getImplementationId()224 uno::Sequence<sal_Int8> SAL_CALL AccessibleStateSetHelper::getImplementationId()
225 {
226     return css::uno::Sequence<sal_Int8>();
227 }
228 
229 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
230