alternative new version of the AppleUtility library
[ardour.git] / libs / appleutility / CoreAudio / PublicUtility / CAPropertyAddress.h
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:
83                                                 CAPropertyAddress()                                                                                                                                                                                                                                     : AudioObjectPropertyAddress() { mSelector = 0; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
84                                                 CAPropertyAddress(AudioObjectPropertySelector inSelector)                                                                                                                                                       : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
85                                                 CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope)                                                                                     : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = kAudioObjectPropertyElementMaster; }
86                                                 CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement)   : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = inElement; }
87                                                 CAPropertyAddress(const AudioObjectPropertyAddress& inAddress)                                                                                                                                          : AudioObjectPropertyAddress(inAddress){}
88                                                 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:
94         static bool                     IsSameAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2)                                                       { return (inAddress1.mScope == inAddress2.mScope) && (inAddress1.mSelector == inAddress2.mSelector) && (inAddress1.mElement == inAddress2.mElement); }
95         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; }
96         static bool                     IsCongruentSelector(AudioObjectPropertySelector inSelector1, AudioObjectPropertySelector inSelector2)                                                           { return (inSelector1 == inSelector2) || (inSelector1 == kAudioObjectPropertySelectorWildcard) || (inSelector2 == kAudioObjectPropertySelectorWildcard); }
97         static bool                     IsCongruentScope(AudioObjectPropertyScope inScope1, AudioObjectPropertyScope inScope2)                                                                                          { return (inScope1 == inScope2) || (inScope1 == kAudioObjectPropertyScopeWildcard) || (inScope2 == kAudioObjectPropertyScopeWildcard); }
98         static bool                     IsCongruentElement(AudioObjectPropertyElement inElement1, AudioObjectPropertyElement inElement2)                                                                        { return (inElement1 == inElement2) || (inElement1 == kAudioObjectPropertyElementWildcard) || (inElement2 == kAudioObjectPropertyElementWildcard); }
99         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); }
100         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         {
106                 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         {
111                 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         {
116                 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         {
121                 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:
137                                                                                         CAPropertyAddressList()                                                                                                                                 : mAddressList(), mToken(NULL) {}
138         explicit                                                                CAPropertyAddressList(void* inToken)                                                                                                    : mAddressList(), mToken(inToken) {}
139         explicit                                                                CAPropertyAddressList(uintptr_t inToken)                                                                                                : mAddressList(), mToken(reinterpret_cast<void*>(inToken)) {}
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; }
142                                                                                         ~CAPropertyAddressList()                                                                                                                                {}
143
144 //      Operations
145 public:
146         void*                                                                   GetToken() const                                                                                                                                                { return mToken; }
147         void                                                                    SetToken(void* inToken)                                                                                                                                 { mToken = inToken; }
148         
149         uintptr_t                                                               GetIntToken() const                                                                                                                                             { return reinterpret_cast<uintptr_t>(mToken); }
150         void                                                                    SetIntToken(uintptr_t inToken)                                                                                                                  { mToken = reinterpret_cast<void*>(inToken); }
151         
152         AudioObjectID                                                   GetAudioObjectIDToken() const                                                                                                                   { return static_cast<AudioObjectID>(reinterpret_cast<uintptr_t>(mToken)); }
153         
154         bool                                                                    IsEmpty() const                                                                                                                                                 { return mAddressList.empty(); }
155         UInt32                                                                  GetNumberItems() const                                                                                                                                  { return ToUInt32(mAddressList.size()); }
156         void                                                                    GetItemByIndex(UInt32 inIndex, AudioObjectPropertyAddress& outAddress) const                    { if(inIndex < mAddressList.size()) { outAddress = mAddressList.at(inIndex); } }
157         const AudioObjectPropertyAddress*               GetItems() const                                                                                                                                                { return &(*mAddressList.begin()); }
158         AudioObjectPropertyAddress*                             GetItems()                                                                                                                                                              { return &(*mAddressList.begin()); }
159         
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(); }
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
163         void                                                                    AppendItem(const AudioObjectPropertyAddress& inAddress)                                                                 { mAddressList.push_back(inAddress); }
164         void                                                                    AppendUniqueItem(const AudioObjectPropertyAddress& inAddress)                                                   { if(!HasItem(inAddress)) { mAddressList.push_back(inAddress); } }
165         void                                                                    AppendUniqueExactItem(const AudioObjectPropertyAddress& inAddress)                                              { if(!HasExactItem(inAddress)) { mAddressList.push_back(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); } }
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); } }
168         void                                                                    EraseItemAtIndex(UInt32 inIndex)                                                                                                                { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.erase(theIterator); } }
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:
191                                                                                                 CAPropertyAddressListVector()                                                                                                           : mAddressListVector() {}
192                                                                                                 CAPropertyAddressListVector(const CAPropertyAddressListVector& inAddressListVector)     : mAddressListVector(inAddressListVector.mAddressListVector) {}
193         CAPropertyAddressListVector&                            operator=(const CAPropertyAddressListVector& inAddressListVector)                                       { mAddressListVector = inAddressListVector.mAddressListVector; return *this; }
194                                                                                                 ~CAPropertyAddressListVector()                                                                                                          {}
195
196 //      Operations
197 public:
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
203         UInt32                                                                          GetNumberItems() const                                                                                                                          { return ToUInt32(mAddressListVector.size()); }
204         const CAPropertyAddressList&                            GetItemByIndex(UInt32 inIndex) const                                                                                            { return mAddressListVector.at(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         
211         void                                                                            AppendItem(const CAPropertyAddressList& inAddressList)                                                          { mAddressListVector.push_back(inAddressList); }
212         void                                                                            EraseAllItems()                                                                                                                                         { mAddressListVector.clear(); }
213         
214 //  Implementation
215 private:
216         typedef std::vector<CAPropertyAddressList>      AddressListVector;
217
218         AddressListVector                                                       mAddressListVector;
219
220 };
221
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
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
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
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
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
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
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