1 /*
2 File: CAPropertyAddress.h
3 Abstract: Part of CoreAudio Utility Classes
4 Version: 1.1
5
6 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
7 Inc. ("Apple") in consideration of your agreement to the following
8 terms, and your use, installation, modification or redistribution of
9 this Apple software constitutes acceptance of these terms. If you do
10 not agree with these terms, please do not use, install, modify or
11 redistribute this Apple software.
12
13 In consideration of your agreement to abide by the following terms, and
14 subject to these terms, Apple grants you a personal, non-exclusive
15 license, under Apple's copyrights in this original Apple software (the
16 "Apple Software"), to use, reproduce, modify and redistribute the Apple
17 Software, with or without modifications, in source and/or binary forms;
18 provided that if you redistribute the Apple Software in its entirety and
19 without modifications, you must retain this notice and the following
20 text and disclaimers in all such redistributions of the Apple Software.
21 Neither the name, trademarks, service marks or logos of Apple Inc. may
22 be used to endorse or promote products derived from the Apple Software
23 without specific prior written permission from Apple. Except as
24 expressly stated in this notice, no other rights or licenses, express or
25 implied, are granted by Apple herein, including but not limited to any
26 patent rights that may be infringed by your derivative works or by other
27 works in which the Apple Software may be incorporated.
28
29 The Apple Software is provided by Apple on an "AS IS" basis. APPLE
30 MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
31 THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
32 FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
33 OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
34
35 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
36 OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
37 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
39 MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
40 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
41 STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
42 POSSIBILITY OF SUCH DAMAGE.
43
44 Copyright (C) 2014 Apple Inc. All Rights Reserved.
45
46 */
47 #if !defined(__CAPropertyAddress_h__)
48 #define __CAPropertyAddress_h__
49
50 //==================================================================================================
51 // Includes
52 //==================================================================================================
53
54 // PublicUtility Includes
55 #include "CADebugMacros.h"
56
57 // System Includes
58 #include <CoreAudio/AudioHardware.h>
59
60 // Standard Library Includes
61 #include <algorithm>
62 #include <functional>
63 #include <vector>
64
65 //==================================================================================================
66 // CAPropertyAddress
67 //
68 // CAPropertyAddress extends the AudioObjectPropertyAddress structure to C++ including constructors
69 // and other utility operations. Note that there is no defined operator< or operator== because the
70 // presence of wildcards for the fields make comparisons ambiguous without specifying whether or
71 // not to take the wildcards into account. Consequently, if you want to use this struct in an STL
72 // data structure, you'll need to specify the approriate function object explicitly in the template
73 // declaration.
74 //==================================================================================================
75
76 struct CAPropertyAddress
77 :
78 public AudioObjectPropertyAddress
79 {
80
81 // Construction/Destruction
82 public:
CAPropertyAddressCAPropertyAddress83 CAPropertyAddress() : AudioObjectPropertyAddress() { mSelector = 0; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
CAPropertyAddressCAPropertyAddress84 CAPropertyAddress(AudioObjectPropertySelector inSelector) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
CAPropertyAddressCAPropertyAddress85 CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = kAudioObjectPropertyElementMaster; }
CAPropertyAddressCAPropertyAddress86 CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = inElement; }
CAPropertyAddressCAPropertyAddress87 CAPropertyAddress(const AudioObjectPropertyAddress& inAddress) : AudioObjectPropertyAddress(inAddress){}
CAPropertyAddressCAPropertyAddress88 CAPropertyAddress(const CAPropertyAddress& inAddress) : AudioObjectPropertyAddress(inAddress){}
89 CAPropertyAddress& operator=(const AudioObjectPropertyAddress& inAddress) { AudioObjectPropertyAddress::operator=(inAddress); return *this; }
90 CAPropertyAddress& operator=(const CAPropertyAddress& inAddress) { AudioObjectPropertyAddress::operator=(inAddress); return *this; }
91
92 // Operations
93 public:
IsSameAddressCAPropertyAddress94 static bool IsSameAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { return (inAddress1.mScope == inAddress2.mScope) && (inAddress1.mSelector == inAddress2.mSelector) && (inAddress1.mElement == inAddress2.mElement); }
IsLessThanAddressCAPropertyAddress95 static bool IsLessThanAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { bool theAnswer = false; if(inAddress1.mScope != inAddress2.mScope) { theAnswer = inAddress1.mScope < inAddress2.mScope; } else if(inAddress1.mSelector != inAddress2.mSelector) { theAnswer = inAddress1.mSelector < inAddress2.mSelector; } else { theAnswer = inAddress1.mElement < inAddress2.mElement; } return theAnswer; }
IsCongruentSelectorCAPropertyAddress96 static bool IsCongruentSelector(AudioObjectPropertySelector inSelector1, AudioObjectPropertySelector inSelector2) { return (inSelector1 == inSelector2) || (inSelector1 == kAudioObjectPropertySelectorWildcard) || (inSelector2 == kAudioObjectPropertySelectorWildcard); }
IsCongruentScopeCAPropertyAddress97 static bool IsCongruentScope(AudioObjectPropertyScope inScope1, AudioObjectPropertyScope inScope2) { return (inScope1 == inScope2) || (inScope1 == kAudioObjectPropertyScopeWildcard) || (inScope2 == kAudioObjectPropertyScopeWildcard); }
IsCongruentElementCAPropertyAddress98 static bool IsCongruentElement(AudioObjectPropertyElement inElement1, AudioObjectPropertyElement inElement2) { return (inElement1 == inElement2) || (inElement1 == kAudioObjectPropertyElementWildcard) || (inElement2 == kAudioObjectPropertyElementWildcard); }
IsCongruentAddressCAPropertyAddress99 static bool IsCongruentAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { return IsCongruentScope(inAddress1.mScope, inAddress2.mScope) && IsCongruentSelector(inAddress1.mSelector, inAddress2.mSelector) && IsCongruentElement(inAddress1.mElement, inAddress2.mElement); }
IsCongruentLessThanAddressCAPropertyAddress100 static bool IsCongruentLessThanAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { bool theAnswer = false; if(!IsCongruentScope(inAddress1.mScope, inAddress2.mScope)) { theAnswer = inAddress1.mScope < inAddress2.mScope; } else if(!IsCongruentSelector(inAddress1.mSelector, inAddress2.mSelector)) { theAnswer = inAddress1.mSelector < inAddress2.mSelector; } else if(!IsCongruentElement(inAddress1.mElement, inAddress2.mElement)) { theAnswer = inAddress1.mElement < inAddress2.mElement; } return theAnswer; }
101
102 // STL Helpers
103 public:
104 struct EqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
105 {
operatorCAPropertyAddress::EqualTo106 bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsSameAddress(inAddress1, inAddress2); }
107 };
108
109 struct LessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
110 {
operatorCAPropertyAddress::LessThan111 bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsLessThanAddress(inAddress1, inAddress2); }
112 };
113
114 struct CongruentEqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
115 {
operatorCAPropertyAddress::CongruentEqualTo116 bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentAddress(inAddress1, inAddress2); }
117 };
118
119 struct CongruentLessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
120 {
operatorCAPropertyAddress::CongruentLessThan121 bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentLessThanAddress(inAddress1, inAddress2); }
122 };
123
124 };
125
126 //==================================================================================================
127 // CAPropertyAddressList
128 //
129 // An auto-resizing array of CAPropertyAddress structures.
130 //==================================================================================================
131
132 class CAPropertyAddressList
133 {
134
135 // Construction/Destruction
136 public:
CAPropertyAddressList()137 CAPropertyAddressList() : mAddressList(), mToken(NULL) {}
CAPropertyAddressList(void * inToken)138 explicit CAPropertyAddressList(void* inToken) : mAddressList(), mToken(inToken) {}
CAPropertyAddressList(uintptr_t inToken)139 explicit CAPropertyAddressList(uintptr_t inToken) : mAddressList(), mToken(reinterpret_cast<void*>(inToken)) {}
CAPropertyAddressList(const CAPropertyAddressList & inAddressList)140 CAPropertyAddressList(const CAPropertyAddressList& inAddressList) : mAddressList(inAddressList.mAddressList), mToken(inAddressList.mToken) {}
141 CAPropertyAddressList& operator=(const CAPropertyAddressList& inAddressList) { mAddressList = inAddressList.mAddressList; mToken = inAddressList.mToken; return *this; }
~CAPropertyAddressList()142 ~CAPropertyAddressList() {}
143
144 // Operations
145 public:
GetToken()146 void* GetToken() const { return mToken; }
SetToken(void * inToken)147 void SetToken(void* inToken) { mToken = inToken; }
148
GetIntToken()149 uintptr_t GetIntToken() const { return reinterpret_cast<uintptr_t>(mToken); }
SetIntToken(uintptr_t inToken)150 void SetIntToken(uintptr_t inToken) { mToken = reinterpret_cast<void*>(inToken); }
151
GetAudioObjectIDToken()152 AudioObjectID GetAudioObjectIDToken() const { return static_cast<AudioObjectID>(reinterpret_cast<uintptr_t>(mToken)); }
153
IsEmpty()154 bool IsEmpty() const { return mAddressList.empty(); }
GetNumberItems()155 UInt32 GetNumberItems() const { return ToUInt32(mAddressList.size()); }
GetItemByIndex(UInt32 inIndex,AudioObjectPropertyAddress & outAddress)156 void GetItemByIndex(UInt32 inIndex, AudioObjectPropertyAddress& outAddress) const { if(inIndex < mAddressList.size()) { outAddress = mAddressList.at(inIndex); } }
GetItems()157 const AudioObjectPropertyAddress* GetItems() const { return &(*mAddressList.begin()); }
GetItems()158 AudioObjectPropertyAddress* GetItems() { return &(*mAddressList.begin()); }
159
HasItem(const AudioObjectPropertyAddress & inAddress)160 bool HasItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::CongruentEqualTo(), inAddress)); return theIterator != mAddressList.end(); }
HasExactItem(const AudioObjectPropertyAddress & inAddress)161 bool HasExactItem(const AudioObjectPropertyAddress& inAddress) const { AddressList::const_iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::EqualTo(), inAddress)); return theIterator != mAddressList.end(); }
162
AppendItem(const AudioObjectPropertyAddress & inAddress)163 void AppendItem(const AudioObjectPropertyAddress& inAddress) { mAddressList.push_back(inAddress); }
AppendUniqueItem(const AudioObjectPropertyAddress & inAddress)164 void AppendUniqueItem(const AudioObjectPropertyAddress& inAddress) { if(!HasItem(inAddress)) { mAddressList.push_back(inAddress); } }
AppendUniqueExactItem(const AudioObjectPropertyAddress & inAddress)165 void AppendUniqueExactItem(const AudioObjectPropertyAddress& inAddress) { if(!HasExactItem(inAddress)) { mAddressList.push_back(inAddress); } }
InsertItemAtIndex(UInt32 inIndex,const AudioObjectPropertyAddress & inAddress)166 void InsertItemAtIndex(UInt32 inIndex, const AudioObjectPropertyAddress& inAddress) { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.insert(theIterator, inAddress); } else { mAddressList.push_back(inAddress); } }
EraseExactItem(const AudioObjectPropertyAddress & inAddress)167 void EraseExactItem(const AudioObjectPropertyAddress& inAddress) { AddressList::iterator theIterator = std::find_if(mAddressList.begin(), mAddressList.end(), std::bind1st(CAPropertyAddress::EqualTo(), inAddress)); if(theIterator != mAddressList.end()) { mAddressList.erase(theIterator); } }
EraseItemAtIndex(UInt32 inIndex)168 void EraseItemAtIndex(UInt32 inIndex) { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.erase(theIterator); } }
EraseAllItems()169 void EraseAllItems() { mAddressList.clear(); }
170
171 // Implementation
172 private:
173 typedef std::vector<CAPropertyAddress> AddressList;
174
175 AddressList mAddressList;
176 void* mToken;
177
178 };
179
180 //==================================================================================================
181 // CAPropertyAddressListVector
182 //
183 // An auto-resizing array of CAPropertyAddressList objects.
184 //==================================================================================================
185
186 class CAPropertyAddressListVector
187 {
188
189 // Construction/Destruction
190 public:
CAPropertyAddressListVector()191 CAPropertyAddressListVector() : mAddressListVector() {}
CAPropertyAddressListVector(const CAPropertyAddressListVector & inAddressListVector)192 CAPropertyAddressListVector(const CAPropertyAddressListVector& inAddressListVector) : mAddressListVector(inAddressListVector.mAddressListVector) {}
193 CAPropertyAddressListVector& operator=(const CAPropertyAddressListVector& inAddressListVector) { mAddressListVector = inAddressListVector.mAddressListVector; return *this; }
~CAPropertyAddressListVector()194 ~CAPropertyAddressListVector() {}
195
196 // Operations
197 public:
IsEmpty()198 bool IsEmpty() const { return mAddressListVector.empty(); }
199 bool HasAnyNonEmptyItems() const;
200 bool HasAnyItemsWithAddress(const AudioObjectPropertyAddress& inAddress) const;
201 bool HasAnyItemsWithExactAddress(const AudioObjectPropertyAddress& inAddress) const;
202
GetNumberItems()203 UInt32 GetNumberItems() const { return ToUInt32(mAddressListVector.size()); }
GetItemByIndex(UInt32 inIndex)204 const CAPropertyAddressList& GetItemByIndex(UInt32 inIndex) const { return mAddressListVector.at(inIndex); }
GetItemByIndex(UInt32 inIndex)205 CAPropertyAddressList& GetItemByIndex(UInt32 inIndex) { return mAddressListVector.at(inIndex); }
206 const CAPropertyAddressList* GetItemByToken(void* inToken) const;
207 CAPropertyAddressList* GetItemByToken(void* inToken);
208 const CAPropertyAddressList* GetItemByIntToken(uintptr_t inToken) const;
209 CAPropertyAddressList* GetItemByIntToken(uintptr_t inToken);
210
AppendItem(const CAPropertyAddressList & inAddressList)211 void AppendItem(const CAPropertyAddressList& inAddressList) { mAddressListVector.push_back(inAddressList); }
EraseAllItems()212 void EraseAllItems() { mAddressListVector.clear(); }
213
214 // Implementation
215 private:
216 typedef std::vector<CAPropertyAddressList> AddressListVector;
217
218 AddressListVector mAddressListVector;
219
220 };
221
HasAnyNonEmptyItems()222 inline bool CAPropertyAddressListVector::HasAnyNonEmptyItems() const
223 {
224 bool theAnswer = false;
225 for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
226 {
227 theAnswer = !theIterator->IsEmpty();
228 }
229 return theAnswer;
230 }
231
HasAnyItemsWithAddress(const AudioObjectPropertyAddress & inAddress)232 inline bool CAPropertyAddressListVector::HasAnyItemsWithAddress(const AudioObjectPropertyAddress& inAddress) const
233 {
234 bool theAnswer = false;
235 for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
236 {
237 theAnswer = theIterator->HasItem(inAddress);
238 }
239 return theAnswer;
240 }
241
HasAnyItemsWithExactAddress(const AudioObjectPropertyAddress & inAddress)242 inline bool CAPropertyAddressListVector::HasAnyItemsWithExactAddress(const AudioObjectPropertyAddress& inAddress) const
243 {
244 bool theAnswer = false;
245 for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
246 {
247 theAnswer = theIterator->HasExactItem(inAddress);
248 }
249 return theAnswer;
250 }
251
GetItemByToken(void * inToken)252 inline const CAPropertyAddressList* CAPropertyAddressListVector::GetItemByToken(void* inToken) const
253 {
254 const CAPropertyAddressList* theAnswer = NULL;
255 bool wasFound = false;
256 for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
257 {
258 if(theIterator->GetToken() == inToken)
259 {
260 wasFound = true;
261 theAnswer = &(*theIterator);
262 }
263 }
264 return theAnswer;
265 }
266
GetItemByToken(void * inToken)267 inline CAPropertyAddressList* CAPropertyAddressListVector::GetItemByToken(void* inToken)
268 {
269 CAPropertyAddressList* theAnswer = NULL;
270 bool wasFound = false;
271 for(AddressListVector::iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
272 {
273 if(theIterator->GetToken() == inToken)
274 {
275 wasFound = true;
276 theAnswer = &(*theIterator);
277 }
278 }
279 return theAnswer;
280 }
281
GetItemByIntToken(uintptr_t inToken)282 inline const CAPropertyAddressList* CAPropertyAddressListVector::GetItemByIntToken(uintptr_t inToken) const
283 {
284 const CAPropertyAddressList* theAnswer = NULL;
285 bool wasFound = false;
286 for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
287 {
288 if(theIterator->GetIntToken() == inToken)
289 {
290 wasFound = true;
291 theAnswer = &(*theIterator);
292 }
293 }
294 return theAnswer;
295 }
296
GetItemByIntToken(uintptr_t inToken)297 inline CAPropertyAddressList* CAPropertyAddressListVector::GetItemByIntToken(uintptr_t inToken)
298 {
299 CAPropertyAddressList* theAnswer = NULL;
300 bool wasFound = false;
301 for(AddressListVector::iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
302 {
303 if(theIterator->GetIntToken() == inToken)
304 {
305 wasFound = true;
306 theAnswer = &(*theIterator);
307 }
308 }
309 return theAnswer;
310 }
311
312 #endif
313