mirror of
https://github.com/morgan9e/VolumeControl
synced 2026-04-14 00:04:05 +09:00
Initial commit
This commit is contained in:
317
driver/PublicUtility/CAAtomic.h
Normal file
317
driver/PublicUtility/CAAtomic.h
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
File: CAAtomic.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
/*
|
||||
This file implements all Atomic operations using Interlocked functions specified in
|
||||
Winbase.h
|
||||
NOTE: According to Microsoft documentation, all Interlocked functions generates a
|
||||
full barrier.
|
||||
On Windows:
|
||||
As the Interlocked functions returns the Old value, Extra checks and operations
|
||||
are made after the atomic operation to return value consistent with OSX counterparts.
|
||||
*/
|
||||
#ifndef __CAAtomic_h__
|
||||
#define __CAAtomic_h__
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include <intrin.h>
|
||||
#pragma intrinsic(_InterlockedOr)
|
||||
#pragma intrinsic(_InterlockedAnd)
|
||||
#else
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
inline void CAMemoryBarrier()
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
MemoryBarrier();
|
||||
#else
|
||||
OSMemoryBarrier();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicAdd32Barrier(SInt32 theAmt, volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
long lRetVal = InterlockedExchangeAdd((volatile long*)theValue, theAmt);
|
||||
// InterlockedExchangeAdd returns the original value which differs from OSX version.
|
||||
// At this point the addition would have occured and hence returning the new value
|
||||
// to keep it sync with OSX.
|
||||
return lRetVal + theAmt;
|
||||
#else
|
||||
return OSAtomicAdd32Barrier(theAmt, (volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicOr32Barrier(UInt32 theMask, volatile UInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
|
||||
// function instead.
|
||||
long j = _InterlockedOr((volatile long*)theValue, theMask);
|
||||
// _InterlockedOr returns the original value which differs from OSX version.
|
||||
// Returning the new value similar to OSX
|
||||
return (SInt32)(j | theMask);
|
||||
#else
|
||||
return OSAtomicOr32Barrier(theMask, (volatile uint32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicAnd32Barrier(UInt32 theMask, volatile UInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedAnd macro is not defined in x86 platform, and hence using the intrinsic
|
||||
// function instead.
|
||||
long j = _InterlockedAnd((volatile long*)theValue, theMask);
|
||||
// _InterlockedAnd returns the original value which differs from OSX version.
|
||||
// Returning the new value similar to OSX
|
||||
return (SInt32)(j & theMask);
|
||||
#else
|
||||
return OSAtomicAnd32Barrier(theMask, (volatile uint32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicCompareAndSwap32Barrier(SInt32 oldValue, SInt32 newValue, volatile SInt32 *theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
// InterlockedCompareExchange returns the old value. But we need to return bool value.
|
||||
long lRetVal = InterlockedCompareExchange((volatile long*)theValue, newValue, oldValue);
|
||||
// Hence we check if the new value is set and if it is we return true else false.
|
||||
// If theValue is equal to oldValue then the swap happens. Otherwise swap doesn't happen.
|
||||
return (oldValue == lRetVal);
|
||||
#else
|
||||
return OSAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline SInt32 CAAtomicIncrement32(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return (SInt32)InterlockedIncrement((volatile long*)theValue);
|
||||
#else
|
||||
return OSAtomicIncrement32((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicDecrement32(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return (SInt32)InterlockedDecrement((volatile long*)theValue);
|
||||
#else
|
||||
return OSAtomicDecrement32((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicIncrement32Barrier(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return CAAtomicIncrement32(theValue);
|
||||
#else
|
||||
return OSAtomicIncrement32Barrier((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline SInt32 CAAtomicDecrement32Barrier(volatile SInt32* theValue)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
return CAAtomicDecrement32(theValue);
|
||||
#else
|
||||
return OSAtomicDecrement32Barrier((volatile int32_t *)theValue);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndClearBarrier(int bitToClear, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = InterlockedBitTestAndReset((long*)theAddress, bitToClear);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndClearBarrier(bitToClear, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndClear(int bitToClear, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = CAAtomicTestAndClearBarrier(bitToClear, (long*)theAddress);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndClear(bitToClear, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CAAtomicTestAndSetBarrier(int bitToSet, void* theAddress)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
BOOL bOldVal = InterlockedBitTestAndSet((long*)theAddress, bitToSet);
|
||||
return (bOldVal ? true : false);
|
||||
#else
|
||||
return OSAtomicTestAndSetBarrier(bitToSet, (volatile void *)theAddress);
|
||||
#endif
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
// int32_t flavors -- for C++ only since we can't overload in C
|
||||
// CFBase.h defines SInt32 as signed int which is similar to int32_t. If CFBase.h is included, then
|
||||
// this will generate redefinition error. But on Mac, CFBase.h, still includes MacTypes.h where
|
||||
// SInt32 is defined as signed long so this would work there.
|
||||
// So in order to fix the redefinition errors, we define these functions only if MacTypes.h is included.
|
||||
#if defined(__cplusplus) && defined(__MACTYPES__) && !__LP64__
|
||||
inline int32_t CAAtomicAdd32Barrier(int32_t theAmt, volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicAdd32Barrier(theAmt, (volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicOr32Barrier(uint32_t theMask, volatile uint32_t* theValue)
|
||||
{
|
||||
return CAAtomicOr32Barrier(theMask, (volatile UInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicAnd32Barrier(uint32_t theMask, volatile uint32_t* theValue)
|
||||
{
|
||||
return CAAtomicAnd32Barrier(theMask, (volatile UInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline bool CAAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatile int32_t *theValue)
|
||||
{
|
||||
return CAAtomicCompareAndSwap32Barrier(oldValue, newValue, (volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicIncrement32(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicIncrement32((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicDecrement32(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicDecrement32((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicIncrement32Barrier(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicIncrement32Barrier((volatile SInt32 *)theValue);
|
||||
}
|
||||
|
||||
inline int32_t CAAtomicDecrement32Barrier(volatile int32_t* theValue)
|
||||
{
|
||||
return CAAtomicDecrement32Barrier((volatile SInt32 *)theValue);
|
||||
}
|
||||
#endif // __cplusplus && !__LP64__
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
#if __LP64__
|
||||
inline bool CAAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue )
|
||||
{
|
||||
return OSAtomicCompareAndSwap64Barrier(__oldValue, __newValue, __theValue);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline bool CAAtomicCompareAndSwapPtrBarrier(void *__oldValue, void *__newValue, volatile void ** __theValue)
|
||||
{
|
||||
#if __LP64__
|
||||
return CAAtomicCompareAndSwap64Barrier((int64_t)__oldValue, (int64_t)__newValue, (int64_t *)__theValue);
|
||||
#else
|
||||
return CAAtomicCompareAndSwap32Barrier((int32_t)__oldValue, (int32_t)__newValue, (int32_t *)__theValue);
|
||||
#endif
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
/* Spinlocks. These use memory barriers as required to synchronize access to shared
|
||||
* memory protected by the lock. The lock operation spins, but employs various strategies
|
||||
* to back off if the lock is held, making it immune to most priority-inversion livelocks.
|
||||
* The try operation immediately returns false if the lock was held, true if it took the
|
||||
* lock. The convention is that unlocked is zero, locked is nonzero.
|
||||
*/
|
||||
#define CA_SPINLOCK_INIT 0
|
||||
|
||||
typedef int32_t CASpinLock;
|
||||
|
||||
bool CASpinLockTry( volatile CASpinLock *__lock );
|
||||
void CASpinLockLock( volatile CASpinLock *__lock );
|
||||
void CASpinLockUnlock( volatile CASpinLock *__lock );
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
|
||||
inline void CASpinLockLock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSSpinLockLock(__lock);
|
||||
#else
|
||||
while (CAAtomicTestAndSetBarrier(0, (void*)__lock))
|
||||
usleep(1000); // ???
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void CASpinLockUnlock( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSSpinLockUnlock(__lock);
|
||||
#else
|
||||
CAAtomicTestAndClearBarrier(0, (void*)__lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool CASpinLockTry( volatile CASpinLock *__lock )
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
return OSSpinLockTry(__lock);
|
||||
#else
|
||||
return (CAAtomicTestAndSetBarrier(0, (void*)__lock) == 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
|
||||
#endif // __CAAtomic_h__
|
||||
242
driver/PublicUtility/CAAtomicStack.h
Normal file
242
driver/PublicUtility/CAAtomicStack.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
File: CAAtomicStack.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAAtomicStack_h__
|
||||
#define __CAAtomicStack_h__
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <libkern/OSAtomic.h>
|
||||
#else
|
||||
#include <CAAtomic.h>
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
|
||||
#include <CoreServices/CoreServices.h>
|
||||
#endif
|
||||
|
||||
// linked list LIFO or FIFO (pop_all_reversed) stack, elements are pushed and popped atomically
|
||||
// class T must implement T *& next().
|
||||
template <class T>
|
||||
class TAtomicStack {
|
||||
public:
|
||||
TAtomicStack() : mHead(NULL) { }
|
||||
|
||||
// non-atomic routines, for use when initializing/deinitializing, operate NON-atomically
|
||||
void push_NA(T *item)
|
||||
{
|
||||
item->next() = mHead;
|
||||
mHead = item;
|
||||
}
|
||||
|
||||
T * pop_NA()
|
||||
{
|
||||
T *result = mHead;
|
||||
if (result)
|
||||
mHead = result->next();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool empty() const { return mHead == NULL; }
|
||||
|
||||
T * head() { return mHead; }
|
||||
|
||||
// atomic routines
|
||||
void push_atomic(T *item)
|
||||
{
|
||||
T *head_;
|
||||
do {
|
||||
head_ = mHead;
|
||||
item->next() = head_;
|
||||
} while (!compare_and_swap(head_, item, &mHead));
|
||||
}
|
||||
|
||||
void push_multiple_atomic(T *item)
|
||||
// pushes entire linked list headed by item
|
||||
{
|
||||
T *head_, *p = item, *tail;
|
||||
// find the last one -- when done, it will be linked to head
|
||||
do {
|
||||
tail = p;
|
||||
p = p->next();
|
||||
} while (p);
|
||||
do {
|
||||
head_ = mHead;
|
||||
tail->next() = head_;
|
||||
} while (!compare_and_swap(head_, item, &mHead));
|
||||
}
|
||||
|
||||
T * pop_atomic_single_reader()
|
||||
// this may only be used when only one thread may potentially pop from the stack.
|
||||
// if multiple threads may pop, this suffers from the ABA problem.
|
||||
// <rdar://problem/4606346> TAtomicStack suffers from the ABA problem
|
||||
{
|
||||
T *result;
|
||||
do {
|
||||
if ((result = mHead) == NULL)
|
||||
break;
|
||||
} while (!compare_and_swap(result, result->next(), &mHead));
|
||||
return result;
|
||||
}
|
||||
|
||||
T * pop_atomic()
|
||||
// This is inefficient for large linked lists.
|
||||
// prefer pop_all() to a series of calls to pop_atomic.
|
||||
// push_multiple_atomic has to traverse the entire list.
|
||||
{
|
||||
T *result = pop_all();
|
||||
if (result) {
|
||||
T *next = result->next();
|
||||
if (next)
|
||||
// push all the remaining items back onto the stack
|
||||
push_multiple_atomic(next);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
T * pop_all()
|
||||
{
|
||||
T *result;
|
||||
do {
|
||||
if ((result = mHead) == NULL)
|
||||
break;
|
||||
} while (!compare_and_swap(result, NULL, &mHead));
|
||||
return result;
|
||||
}
|
||||
|
||||
T* pop_all_reversed()
|
||||
{
|
||||
TAtomicStack<T> reversed;
|
||||
T *p = pop_all(), *next;
|
||||
while (p != NULL) {
|
||||
next = p->next();
|
||||
reversed.push_NA(p);
|
||||
p = next;
|
||||
}
|
||||
return reversed.mHead;
|
||||
}
|
||||
|
||||
static bool compare_and_swap(T *oldvalue, T *newvalue, T **pvalue)
|
||||
{
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
#if TARGET_OS_MAC
|
||||
#if __LP64__
|
||||
return ::OSAtomicCompareAndSwap64Barrier(int64_t(oldvalue), int64_t(newvalue), (int64_t *)pvalue);
|
||||
#elif MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
return ::OSAtomicCompareAndSwap32Barrier(int32_t(oldvalue), int32_t(newvalue), (int32_t *)pvalue);
|
||||
#else
|
||||
return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
|
||||
#endif
|
||||
#else
|
||||
//return ::CompareAndSwap(UInt32(oldvalue), UInt32(newvalue), (UInt32 *)pvalue);
|
||||
return CAAtomicCompareAndSwap32Barrier(SInt32(oldvalue), SInt32(newvalue), (SInt32*)pvalue);
|
||||
#endif
|
||||
#pragma clang diagnostic pop
|
||||
}
|
||||
|
||||
protected:
|
||||
T * mHead;
|
||||
};
|
||||
|
||||
#if ((MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) && !TARGET_OS_WIN32)
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
class CAAtomicStack {
|
||||
public:
|
||||
CAAtomicStack(size_t nextPtrOffset) : mNextPtrOffset(nextPtrOffset) {
|
||||
/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
|
||||
mHead.opaque1 = 0; mHead.opaque2 = 0;
|
||||
}
|
||||
// a subset of the above
|
||||
void push_atomic(void *p) { OSAtomicEnqueue(&mHead, p, mNextPtrOffset); }
|
||||
void push_NA(void *p) { push_atomic(p); }
|
||||
|
||||
void * pop_atomic() { return OSAtomicDequeue(&mHead, mNextPtrOffset); }
|
||||
void * pop_atomic_single_reader() { return pop_atomic(); }
|
||||
void * pop_NA() { return pop_atomic(); }
|
||||
|
||||
private:
|
||||
OSQueueHead mHead;
|
||||
size_t mNextPtrOffset;
|
||||
};
|
||||
|
||||
// a more efficient subset of TAtomicStack using OSQueue.
|
||||
template <class T>
|
||||
class TAtomicStack2 {
|
||||
public:
|
||||
TAtomicStack2() {
|
||||
/*OSQueueHead h = OS_ATOMIC_QUEUE_INIT; mHead = h;*/
|
||||
mHead.opaque1 = 0; mHead.opaque2 = 0;
|
||||
mNextPtrOffset = -1;
|
||||
}
|
||||
void push_atomic(T *item) {
|
||||
if (mNextPtrOffset < 0) {
|
||||
T **pnext = &item->next(); // hack around offsetof not working with C++
|
||||
mNextPtrOffset = (Byte *)pnext - (Byte *)item;
|
||||
}
|
||||
OSAtomicEnqueue(&mHead, item, mNextPtrOffset);
|
||||
}
|
||||
void push_NA(T *item) { push_atomic(item); }
|
||||
|
||||
T * pop_atomic() { return (T *)OSAtomicDequeue(&mHead, mNextPtrOffset); }
|
||||
T * pop_atomic_single_reader() { return pop_atomic(); }
|
||||
T * pop_NA() { return pop_atomic(); }
|
||||
|
||||
// caution: do not try to implement pop_all_reversed here. the writer could add new elements
|
||||
// while the reader is trying to pop old ones!
|
||||
|
||||
private:
|
||||
OSQueueHead mHead;
|
||||
ssize_t mNextPtrOffset;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#define TAtomicStack2 TAtomicStack
|
||||
|
||||
#endif // MAC_OS_X_VERSION_MAX_ALLOWED && !TARGET_OS_WIN32
|
||||
|
||||
#endif // __CAAtomicStack_h__
|
||||
508
driver/PublicUtility/CAAutoDisposer.h
Normal file
508
driver/PublicUtility/CAAutoDisposer.h
Normal file
@@ -0,0 +1,508 @@
|
||||
/*
|
||||
File: CAAutoDisposer.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAPtr_h__)
|
||||
#define __CAPtr_h__
|
||||
|
||||
#include <stdlib.h> // for malloc
|
||||
#include <new> // for bad_alloc
|
||||
#include <string.h> // for memset
|
||||
|
||||
inline void* CA_malloc(size_t size)
|
||||
{
|
||||
void* p = malloc(size);
|
||||
if (!p && size) throw std::bad_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
inline void* CA_realloc(void* old, size_t size)
|
||||
{
|
||||
#if TARGET_OS_WIN32
|
||||
void* p = realloc(old, size);
|
||||
#else
|
||||
void* p = reallocf(old, size); // reallocf ensures the old pointer is freed if memory is full (p is NULL).
|
||||
#endif
|
||||
if (!p && size) throw std::bad_alloc();
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifndef UINTPTR_MAX
|
||||
#if __LP64__
|
||||
#define UINTPTR_MAX 18446744073709551615ULL
|
||||
#else
|
||||
#define UINTPTR_MAX 4294967295U
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void* CA_calloc(size_t n, size_t size)
|
||||
{
|
||||
// ensure that multiplication will not overflow
|
||||
if (n && UINTPTR_MAX / n < size) throw std::bad_alloc();
|
||||
|
||||
size_t nsize = n*size;
|
||||
void* p = malloc(nsize);
|
||||
if (!p && nsize) throw std::bad_alloc();
|
||||
|
||||
memset(p, 0, nsize);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
// helper class for automatic conversions
|
||||
template <typename T>
|
||||
struct CAPtrRef
|
||||
{
|
||||
T* ptr_;
|
||||
|
||||
explicit CAPtrRef(T* ptr) : ptr_(ptr) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CAAutoFree
|
||||
{
|
||||
private:
|
||||
T* ptr_;
|
||||
|
||||
public:
|
||||
|
||||
CAAutoFree() : ptr_(0) {}
|
||||
|
||||
explicit CAAutoFree(T* ptr) : ptr_(ptr) {}
|
||||
|
||||
template<typename U>
|
||||
CAAutoFree(CAAutoFree<U>& that) : ptr_(that.release()) {} // take ownership
|
||||
|
||||
// C++ std says: a template constructor is never a copy constructor
|
||||
CAAutoFree(CAAutoFree<T>& that) : ptr_(that.release()) {} // take ownership
|
||||
|
||||
CAAutoFree(size_t n, bool clear = false)
|
||||
// this becomes an ambiguous call if n == 0
|
||||
: ptr_(0)
|
||||
{
|
||||
size_t maxItems = ~size_t(0) / sizeof(T);
|
||||
if (n > maxItems)
|
||||
throw std::bad_alloc();
|
||||
|
||||
ptr_ = static_cast<T*>(clear ? CA_calloc(n, sizeof(T)) : CA_malloc(n * sizeof(T)));
|
||||
}
|
||||
|
||||
~CAAutoFree() { free(); }
|
||||
|
||||
void alloc(size_t numItems, bool clear = false)
|
||||
{
|
||||
size_t maxItems = ~size_t(0) / sizeof(T);
|
||||
if (numItems > maxItems) throw std::bad_alloc();
|
||||
|
||||
free();
|
||||
ptr_ = static_cast<T*>(clear ? CA_calloc(numItems, sizeof(T)) : CA_malloc(numItems * sizeof(T)));
|
||||
}
|
||||
|
||||
void allocBytes(size_t numBytes, bool clear = false)
|
||||
{
|
||||
free();
|
||||
ptr_ = static_cast<T*>(clear ? CA_calloc(1, numBytes) : CA_malloc(numBytes));
|
||||
}
|
||||
|
||||
void reallocBytes(size_t numBytes)
|
||||
{
|
||||
ptr_ = static_cast<T*>(CA_realloc(ptr_, numBytes));
|
||||
}
|
||||
|
||||
void reallocItems(size_t numItems)
|
||||
{
|
||||
size_t maxItems = ~size_t(0) / sizeof(T);
|
||||
if (numItems > maxItems) throw std::bad_alloc();
|
||||
|
||||
ptr_ = static_cast<T*>(CA_realloc(ptr_, numItems * sizeof(T)));
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
CAAutoFree& operator=(CAAutoFree<U>& that)
|
||||
{
|
||||
set(that.release()); // take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAutoFree& operator=(CAAutoFree& that)
|
||||
{
|
||||
set(that.release()); // take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAutoFree& operator=(T* ptr)
|
||||
{
|
||||
set(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
CAAutoFree& operator=(U* ptr)
|
||||
{
|
||||
set(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator*() const { return *ptr_; }
|
||||
T* operator->() const { return ptr_; }
|
||||
|
||||
T* operator()() const { return ptr_; }
|
||||
T* get() const { return ptr_; }
|
||||
operator T*() const { return ptr_; }
|
||||
|
||||
bool operator==(CAAutoFree const& that) const { return ptr_ == that.ptr_; }
|
||||
bool operator!=(CAAutoFree const& that) const { return ptr_ != that.ptr_; }
|
||||
bool operator==(T* ptr) const { return ptr_ == ptr; }
|
||||
bool operator!=(T* ptr) const { return ptr_ != ptr; }
|
||||
|
||||
T* release()
|
||||
{
|
||||
// release ownership
|
||||
T* result = ptr_;
|
||||
ptr_ = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void set(T* ptr)
|
||||
{
|
||||
if (ptr != ptr_)
|
||||
{
|
||||
::free(ptr_);
|
||||
ptr_ = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
set(0);
|
||||
}
|
||||
|
||||
|
||||
// automatic conversions to allow assignment from results of functions.
|
||||
// hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
|
||||
CAAutoFree(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
|
||||
|
||||
CAAutoFree& operator=(CAPtrRef<T> ref)
|
||||
{
|
||||
set(ref.ptr_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
operator CAPtrRef<U>()
|
||||
{ return CAPtrRef<U>(release()); }
|
||||
|
||||
template<typename U>
|
||||
operator CAAutoFree<U>()
|
||||
{ return CAAutoFree<U>(release()); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class CAAutoDelete
|
||||
{
|
||||
private:
|
||||
T* ptr_;
|
||||
|
||||
public:
|
||||
CAAutoDelete() : ptr_(0) {}
|
||||
|
||||
explicit CAAutoDelete(T* ptr) : ptr_(ptr) {}
|
||||
|
||||
template<typename U>
|
||||
CAAutoDelete(CAAutoDelete<U>& that) : ptr_(that.release()) {} // take ownership
|
||||
|
||||
// C++ std says: a template constructor is never a copy constructor
|
||||
CAAutoDelete(CAAutoDelete<T>& that) : ptr_(that.release()) {} // take ownership
|
||||
|
||||
~CAAutoDelete() { free(); }
|
||||
|
||||
template <typename U>
|
||||
CAAutoDelete& operator=(CAAutoDelete<U>& that)
|
||||
{
|
||||
set(that.release()); // take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAutoDelete& operator=(CAAutoDelete& that)
|
||||
{
|
||||
set(that.release()); // take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAutoDelete& operator=(T* ptr)
|
||||
{
|
||||
set(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
CAAutoDelete& operator=(U* ptr)
|
||||
{
|
||||
set(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator*() const { return *ptr_; }
|
||||
T* operator->() const { return ptr_; }
|
||||
|
||||
T* operator()() const { return ptr_; }
|
||||
T* get() const { return ptr_; }
|
||||
operator T*() const { return ptr_; }
|
||||
|
||||
bool operator==(CAAutoDelete const& that) const { return ptr_ == that.ptr_; }
|
||||
bool operator!=(CAAutoDelete const& that) const { return ptr_ != that.ptr_; }
|
||||
bool operator==(T* ptr) const { return ptr_ == ptr; }
|
||||
bool operator!=(T* ptr) const { return ptr_ != ptr; }
|
||||
|
||||
T* release()
|
||||
{
|
||||
// release ownership
|
||||
T* result = ptr_;
|
||||
ptr_ = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void set(T* ptr)
|
||||
{
|
||||
if (ptr != ptr_)
|
||||
{
|
||||
delete ptr_;
|
||||
ptr_ = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
set(0);
|
||||
}
|
||||
|
||||
|
||||
// automatic conversions to allow assignment from results of functions.
|
||||
// hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
|
||||
CAAutoDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
|
||||
|
||||
CAAutoDelete& operator=(CAPtrRef<T> ref)
|
||||
{
|
||||
set(ref.ptr_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
operator CAPtrRef<U>()
|
||||
{ return CAPtrRef<U>(release()); }
|
||||
|
||||
template<typename U>
|
||||
operator CAAutoFree<U>()
|
||||
{ return CAAutoFree<U>(release()); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class CAAutoArrayDelete
|
||||
{
|
||||
private:
|
||||
T* ptr_;
|
||||
|
||||
public:
|
||||
CAAutoArrayDelete() : ptr_(0) {}
|
||||
|
||||
explicit CAAutoArrayDelete(T* ptr) : ptr_(ptr) {}
|
||||
|
||||
template<typename U>
|
||||
CAAutoArrayDelete(CAAutoArrayDelete<U>& that) : ptr_(that.release()) {} // take ownership
|
||||
|
||||
// C++ std says: a template constructor is never a copy constructor
|
||||
CAAutoArrayDelete(CAAutoArrayDelete<T>& that) : ptr_(that.release()) {} // take ownership
|
||||
|
||||
// this becomes an ambiguous call if n == 0
|
||||
CAAutoArrayDelete(size_t n) : ptr_(new T[n]) {}
|
||||
|
||||
~CAAutoArrayDelete() { free(); }
|
||||
|
||||
void alloc(size_t numItems)
|
||||
{
|
||||
free();
|
||||
ptr_ = new T [numItems];
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
CAAutoArrayDelete& operator=(CAAutoArrayDelete<U>& that)
|
||||
{
|
||||
set(that.release()); // take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAutoArrayDelete& operator=(CAAutoArrayDelete& that)
|
||||
{
|
||||
set(that.release()); // take ownership
|
||||
return *this;
|
||||
}
|
||||
|
||||
CAAutoArrayDelete& operator=(T* ptr)
|
||||
{
|
||||
set(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
CAAutoArrayDelete& operator=(U* ptr)
|
||||
{
|
||||
set(ptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator*() const { return *ptr_; }
|
||||
T* operator->() const { return ptr_; }
|
||||
|
||||
T* operator()() const { return ptr_; }
|
||||
T* get() const { return ptr_; }
|
||||
operator T*() const { return ptr_; }
|
||||
|
||||
bool operator==(CAAutoArrayDelete const& that) const { return ptr_ == that.ptr_; }
|
||||
bool operator!=(CAAutoArrayDelete const& that) const { return ptr_ != that.ptr_; }
|
||||
bool operator==(T* ptr) const { return ptr_ == ptr; }
|
||||
bool operator!=(T* ptr) const { return ptr_ != ptr; }
|
||||
|
||||
T* release()
|
||||
{
|
||||
// release ownership
|
||||
T* result = ptr_;
|
||||
ptr_ = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
void set(T* ptr)
|
||||
{
|
||||
if (ptr != ptr_)
|
||||
{
|
||||
delete [] ptr_;
|
||||
ptr_ = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
void free()
|
||||
{
|
||||
set(0);
|
||||
}
|
||||
|
||||
|
||||
// automatic conversions to allow assignment from results of functions.
|
||||
// hard to explain. see auto_ptr implementation and/or Josuttis' STL book.
|
||||
CAAutoArrayDelete(CAPtrRef<T> ref) : ptr_(ref.ptr_) { }
|
||||
|
||||
CAAutoArrayDelete& operator=(CAPtrRef<T> ref)
|
||||
{
|
||||
set(ref.ptr_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
operator CAPtrRef<U>()
|
||||
{ return CAPtrRef<U>(release()); }
|
||||
|
||||
template<typename U>
|
||||
operator CAAutoArrayDelete<U>()
|
||||
{ return CAAutoFree<U>(release()); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// convenience function
|
||||
template <typename T>
|
||||
void free(CAAutoFree<T>& p)
|
||||
{
|
||||
p.free();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
// example program showing ownership transfer
|
||||
|
||||
CAAutoFree<char> source()
|
||||
{
|
||||
// source allocates and returns ownership to the caller.
|
||||
const char* str = "this is a test";
|
||||
size_t size = strlen(str) + 1;
|
||||
CAAutoFree<char> captr(size, false);
|
||||
strlcpy(captr(), str, size);
|
||||
printf("source %08X %08X '%s'\n", &captr, captr(), captr());
|
||||
return captr;
|
||||
}
|
||||
|
||||
void user(CAAutoFree<char> const& captr)
|
||||
{
|
||||
// passed by const reference. user can access the pointer but does not take ownership.
|
||||
printf("user: %08X %08X '%s'\n", &captr, captr(), captr());
|
||||
}
|
||||
|
||||
void sink(CAAutoFree<char> captr)
|
||||
{
|
||||
// passed by value. sink takes ownership and frees the pointer on return.
|
||||
printf("sink: %08X %08X '%s'\n", &captr, captr(), captr());
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char * const argv[])
|
||||
{
|
||||
|
||||
CAAutoFree<char> captr(source());
|
||||
printf("main captr A %08X %08X\n", &captr, captr());
|
||||
user(captr);
|
||||
sink(captr);
|
||||
printf("main captr B %08X %08X\n", &captr, captr());
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
206
driver/PublicUtility/CABitOperations.h
Normal file
206
driver/PublicUtility/CABitOperations.h
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
File: CABitOperations.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef _CABitOperations_h_
|
||||
#define _CABitOperations_h_
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
//#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.h>
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#else
|
||||
// #include <MacTypes.h>
|
||||
#include "CFBase.h"
|
||||
#endif
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
// return whether a number is a power of two
|
||||
inline UInt32 IsPowerOfTwo(UInt32 x)
|
||||
{
|
||||
return (x & (x-1)) == 0;
|
||||
}
|
||||
|
||||
// count the leading zeros in a word
|
||||
// Metrowerks Codewarrior. powerpc native count leading zeros instruction:
|
||||
// I think it's safe to remove this ...
|
||||
//#define CountLeadingZeroes(x) ((int)__cntlzw((unsigned int)x))
|
||||
|
||||
inline UInt32 CountLeadingZeroes(UInt32 arg)
|
||||
{
|
||||
// GNUC / LLVM have a builtin
|
||||
#if defined(__GNUC__) || defined(__llvm___)
|
||||
#if (TARGET_CPU_X86 || TARGET_CPU_X86_64)
|
||||
if (arg == 0) return 32;
|
||||
#endif // TARGET_CPU_X86 || TARGET_CPU_X86_64
|
||||
return __builtin_clz(arg);
|
||||
#elif TARGET_OS_WIN32
|
||||
UInt32 tmp;
|
||||
__asm{
|
||||
bsr eax, arg
|
||||
mov ecx, 63
|
||||
cmovz eax, ecx
|
||||
xor eax, 31
|
||||
mov tmp, eax // this moves the result in tmp to return.
|
||||
}
|
||||
return tmp;
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif // defined(__GNUC__)
|
||||
}
|
||||
// Alias (with different spelling)
|
||||
#define CountLeadingZeros CountLeadingZeroes
|
||||
|
||||
inline UInt32 CountLeadingZeroesLong(UInt64 arg)
|
||||
{
|
||||
// GNUC / LLVM have a builtin
|
||||
#if defined(__GNUC__) || defined(__llvm___)
|
||||
#if (TARGET_CPU_X86 || TARGET_CPU_X86_64)
|
||||
if (arg == 0) return 64;
|
||||
#endif // TARGET_CPU_X86 || TARGET_CPU_X86_64
|
||||
return __builtin_clzll(arg);
|
||||
#elif TARGET_OS_WIN32
|
||||
UInt32 x = CountLeadingZeroes((UInt32)(arg >> 32));
|
||||
if(x < 32)
|
||||
return x;
|
||||
else
|
||||
return 32+CountLeadingZeroes((UInt32)arg);
|
||||
#else
|
||||
#error "Unsupported architecture"
|
||||
#endif // defined(__GNUC__)
|
||||
}
|
||||
#define CountLeadingZerosLong CountLeadingZeroesLong
|
||||
|
||||
// count trailing zeroes
|
||||
inline UInt32 CountTrailingZeroes(UInt32 x)
|
||||
{
|
||||
return 32 - CountLeadingZeroes(~x & (x-1));
|
||||
}
|
||||
|
||||
// count leading ones
|
||||
inline UInt32 CountLeadingOnes(UInt32 x)
|
||||
{
|
||||
return CountLeadingZeroes(~x);
|
||||
}
|
||||
|
||||
// count trailing ones
|
||||
inline UInt32 CountTrailingOnes(UInt32 x)
|
||||
{
|
||||
return 32 - CountLeadingZeroes(x & (~x-1));
|
||||
}
|
||||
|
||||
// number of bits required to represent x.
|
||||
inline UInt32 NumBits(UInt32 x)
|
||||
{
|
||||
return 32 - CountLeadingZeroes(x);
|
||||
}
|
||||
|
||||
// base 2 log of next power of two greater or equal to x
|
||||
inline UInt32 Log2Ceil(UInt32 x)
|
||||
{
|
||||
return 32 - CountLeadingZeroes(x - 1);
|
||||
}
|
||||
|
||||
// base 2 log of next power of two less or equal to x
|
||||
inline UInt32 Log2Floor(UInt32 x)
|
||||
{
|
||||
return 32 - CountLeadingZeroes(x) - 1;
|
||||
}
|
||||
|
||||
// next power of two greater or equal to x
|
||||
inline UInt32 NextPowerOfTwo(UInt32 x)
|
||||
{
|
||||
return 1 << Log2Ceil(x);
|
||||
}
|
||||
|
||||
// counting the one bits in a word
|
||||
inline UInt32 CountOnes(UInt32 x)
|
||||
{
|
||||
// secret magic algorithm for counting bits in a word.
|
||||
x = x - ((x >> 1) & 0x55555555);
|
||||
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
||||
return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
|
||||
}
|
||||
|
||||
// counting the zero bits in a word
|
||||
inline UInt32 CountZeroes(UInt32 x)
|
||||
{
|
||||
return CountOnes(~x);
|
||||
}
|
||||
|
||||
// return the bit position (0..31) of the least significant bit
|
||||
inline UInt32 LSBitPos(UInt32 x)
|
||||
{
|
||||
return CountTrailingZeroes(x & -(SInt32)x);
|
||||
}
|
||||
|
||||
// isolate the least significant bit
|
||||
inline UInt32 LSBit(UInt32 x)
|
||||
{
|
||||
return x & -(SInt32)x;
|
||||
}
|
||||
|
||||
// return the bit position (0..31) of the most significant bit
|
||||
inline UInt32 MSBitPos(UInt32 x)
|
||||
{
|
||||
return 31 - CountLeadingZeroes(x);
|
||||
}
|
||||
|
||||
// isolate the most significant bit
|
||||
inline UInt32 MSBit(UInt32 x)
|
||||
{
|
||||
return 1 << MSBitPos(x);
|
||||
}
|
||||
|
||||
// Division optimized for power of 2 denominators
|
||||
inline UInt32 DivInt(UInt32 numerator, UInt32 denominator)
|
||||
{
|
||||
if(IsPowerOfTwo(denominator))
|
||||
return numerator >> (31 - CountLeadingZeroes(denominator));
|
||||
else
|
||||
return numerator/denominator;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
821
driver/PublicUtility/CACFArray.cpp
Normal file
821
driver/PublicUtility/CACFArray.cpp
Normal file
@@ -0,0 +1,821 @@
|
||||
/*
|
||||
File: CACFArray.cpp
|
||||
Abstract: CACFArray.h
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CACFArray.h"
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CACFDictionary.h"
|
||||
#include "CACFNumber.h"
|
||||
#include "CACFString.h"
|
||||
|
||||
//=============================================================================
|
||||
// CACFArray
|
||||
//=============================================================================
|
||||
|
||||
bool CACFArray::HasItem(const void* inItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
if(mCFArray != NULL)
|
||||
{
|
||||
CFRange theRange = { 0, CFArrayGetCount(mCFArray)};
|
||||
theAnswer = CFArrayContainsValue(mCFArray, theRange, inItem);
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetIndexOfItem(const void* inItem, UInt32& outIndex) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
outIndex = 0;
|
||||
if(mCFArray != NULL)
|
||||
{
|
||||
CFRange theRange = { 0, CFArrayGetCount(mCFArray)};
|
||||
CFIndex theIndex = CFArrayGetFirstIndexOfValue(mCFArray, theRange, inItem);
|
||||
if(theIndex != -1)
|
||||
{
|
||||
theAnswer = true;
|
||||
outIndex = ToUInt32(theIndex);
|
||||
}
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetBool(UInt32 inIndex, bool& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inIndex, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
|
||||
{
|
||||
outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
|
||||
theAnswer = true;
|
||||
}
|
||||
else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
SInt32 theNumericValue = 0;
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
|
||||
outValue = theNumericValue != 0;
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetSInt32(UInt32 inIndex, SInt32& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt32Type, &outItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetUInt32(UInt32 inIndex, UInt32& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt32Type, &outItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetSInt64(UInt32 inIndex, SInt64& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt64Type, &outItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetUInt64(UInt32 inIndex, UInt64& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberSInt64Type, &outItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetFloat32(UInt32 inIndex, Float32& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberFloat32Type, &outItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetFloat64(UInt32 inIndex, Float64& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theItem), kCFNumberFloat64Type, &outItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::Get4CC(UInt32 inIndex, UInt32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inIndex, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
else if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
|
||||
{
|
||||
CFStringRef theString = static_cast<CFStringRef>(theValue);
|
||||
if(CFStringGetLength(theString) == 4)
|
||||
{
|
||||
char theCString[5];
|
||||
CFStringGetCString(theString, theCString, 5, kCFStringEncodingASCII);
|
||||
outValue = CFSwapInt32BigToHost(*reinterpret_cast<UInt32*>(theCString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetString(UInt32 inIndex, CFStringRef& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFStringGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFStringRef>(theItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetArray(UInt32 inIndex, CFArrayRef& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFArrayGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFArrayRef>(theItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetDictionary(UInt32 inIndex, CFDictionaryRef& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFDictionaryGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFDictionaryRef>(theItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetData(UInt32 inIndex, CFDataRef& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFDataGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFDataRef>(theItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetUUID(UInt32 inIndex, CFUUIDRef& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFUUIDGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFUUIDRef>(theItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::GetCFType(UInt32 inIndex, CFTypeRef& outItem) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && (inIndex < GetNumberItems()))
|
||||
{
|
||||
outItem = CFArrayGetValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex));
|
||||
theAnswer = outItem != NULL;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CACFArray::GetCACFString(UInt32 inIndex, CACFString& outItem) const
|
||||
{
|
||||
outItem = static_cast<CFStringRef>(NULL);
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFStringGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFStringRef>(theItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CACFArray::GetCACFArray(UInt32 inIndex, CACFArray& outItem) const
|
||||
{
|
||||
outItem = static_cast<CFArrayRef>(NULL);
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFArrayGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFArrayRef>(theItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CACFArray::GetCACFDictionary(UInt32 inIndex, CACFDictionary& outItem) const
|
||||
{
|
||||
outItem = static_cast<CFDictionaryRef>(NULL);
|
||||
CFTypeRef theItem = NULL;
|
||||
if(GetCFType(inIndex, theItem))
|
||||
{
|
||||
if((theItem != NULL) && (CFGetTypeID(theItem) == CFDictionaryGetTypeID()))
|
||||
{
|
||||
outItem = static_cast<CFDictionaryRef>(theItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CACFArray::AppendBool(bool inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFBoolean theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = AppendCFType(theItem.GetCFBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::AppendSInt32(SInt32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = AppendCFType(theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::AppendUInt32(UInt32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = AppendCFType(theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::AppendSInt64(SInt64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = AppendCFType(theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::AppendUInt64(UInt64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = AppendCFType(theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::AppendFloat32(Float32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = AppendCFType(theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::AppendFloat64(Float64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = AppendCFType(theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::AppendString(const CFStringRef inItem)
|
||||
{
|
||||
return AppendCFType(inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::AppendArray(const CFArrayRef inItem)
|
||||
{
|
||||
return AppendCFType(inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::AppendDictionary(const CFDictionaryRef inItem)
|
||||
{
|
||||
return AppendCFType(inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::AppendData(const CFDataRef inItem)
|
||||
{
|
||||
return AppendCFType(inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::AppendCFType(const CFTypeRef inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CFArrayAppendValue(mCFArray, inItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertBool(UInt32 inIndex, bool inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFBoolean theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = InsertCFType(inIndex, theItem.GetCFBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertSInt32(UInt32 inIndex, SInt32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertUInt32(UInt32 inIndex, UInt32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertSInt64(UInt32 inIndex, SInt64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertUInt64(UInt32 inIndex, UInt64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertFloat32(UInt32 inIndex, Float32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertFloat64(UInt32 inIndex, Float64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = InsertCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::InsertString(UInt32 inIndex, const CFStringRef inItem)
|
||||
{
|
||||
return InsertCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::InsertArray(UInt32 inIndex, const CFArrayRef inItem)
|
||||
{
|
||||
return InsertCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::InsertDictionary(UInt32 inIndex, const CFDictionaryRef inItem)
|
||||
{
|
||||
return InsertCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::InsertData(UInt32 inIndex, const CFDataRef inItem)
|
||||
{
|
||||
return InsertCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::InsertCFType(UInt32 inIndex, const CFTypeRef inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable)
|
||||
{
|
||||
if(inIndex < GetNumberItems())
|
||||
{
|
||||
CFArrayInsertValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex), inItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
CFArrayAppendValue(mCFArray, inItem);
|
||||
}
|
||||
theAnswer = true;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetBool(UInt32 inIndex, bool inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CACFBoolean theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = SetCFType(inIndex, theItem.GetCFBoolean());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetSInt32(UInt32 inIndex, SInt32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetUInt32(UInt32 inIndex, UInt32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetSInt64(UInt32 inIndex, SInt64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetUInt64(UInt32 inIndex, UInt64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetFloat32(UInt32 inIndex, Float32 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetFloat64(UInt32 inIndex, Float64 inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CACFNumber theItem(inItem);
|
||||
if(theItem.IsValid())
|
||||
{
|
||||
theAnswer = SetCFType(inIndex, theItem.GetCFNumber());
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFArray::SetString(UInt32 inIndex, const CFStringRef inItem)
|
||||
{
|
||||
return SetCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::SetArray(UInt32 inIndex, const CFArrayRef inItem)
|
||||
{
|
||||
return SetCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::SetDictionary(UInt32 inIndex, const CFDictionaryRef inItem)
|
||||
{
|
||||
return SetCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::SetData(UInt32 inIndex, const CFDataRef inItem)
|
||||
{
|
||||
return SetCFType(inIndex, inItem);
|
||||
}
|
||||
|
||||
bool CACFArray::SetCFType(UInt32 inIndex, const CFTypeRef inItem)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if((mCFArray != NULL) && mMutable && (inIndex <= GetNumberItems()))
|
||||
{
|
||||
CFArraySetValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex), inItem);
|
||||
theAnswer = true;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
195
driver/PublicUtility/CACFArray.h
Normal file
195
driver/PublicUtility/CACFArray.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
File: CACFArray.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CACFArray_h__)
|
||||
#define __CACFArray_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
|
||||
//=============================================================================
|
||||
// Types
|
||||
//=============================================================================
|
||||
|
||||
class CACFDictionary;
|
||||
class CACFString;
|
||||
|
||||
//=============================================================================
|
||||
// CACFArray
|
||||
//=============================================================================
|
||||
|
||||
class CACFArray
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFArray() : mCFArray(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)), mRelease(true), mMutable(true) {}
|
||||
explicit CACFArray(bool inRelease) : mCFArray(CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks)), mRelease(inRelease), mMutable(true) {}
|
||||
CACFArray(UInt32 inMaxNumberItems, bool inRelease) : mCFArray(CFArrayCreateMutable(NULL, static_cast<CFIndex>(inMaxNumberItems), &kCFTypeArrayCallBacks)), mRelease(inRelease), mMutable(true) {}
|
||||
CACFArray(CFArrayRef inCFArray, bool inRelease) : mCFArray(const_cast<CFMutableArrayRef>(inCFArray)), mRelease(inRelease), mMutable(false) {}
|
||||
CACFArray(CFMutableArrayRef inCFArray, bool inRelease) : mCFArray(inCFArray), mRelease(inRelease), mMutable(true) {}
|
||||
CACFArray(const CACFArray& inArray) : mCFArray(inArray.mCFArray), mRelease(inArray.mRelease), mMutable(inArray.mMutable) { Retain(); }
|
||||
CACFArray& operator=(const CACFArray& inArray) { Release(); mCFArray = inArray.mCFArray; mRelease = inArray.mRelease; mMutable = inArray.mMutable; Retain(); return *this; }
|
||||
CACFArray& operator=(CFArrayRef inCFArray) { Release(); mCFArray = const_cast<CFMutableArrayRef>(inCFArray); mMutable = false; Retain(); return *this; }
|
||||
CACFArray& operator=(CFMutableArrayRef inCFArray) { Release(); mCFArray = inCFArray; mMutable = true; Retain(); return *this; }
|
||||
~CACFArray() { Release(); }
|
||||
|
||||
private:
|
||||
void Retain() { if(mRelease && (mCFArray != NULL)) { CFRetain(mCFArray); } }
|
||||
void Release() { if(mRelease && (mCFArray != NULL)) { CFRelease(mCFArray); } }
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
bool IsValid() const { return mCFArray != NULL; }
|
||||
bool IsMutable() const { return mMutable; }
|
||||
bool CanModify() const { return mMutable && (mCFArray != NULL); }
|
||||
|
||||
bool WillRelease() const { return mRelease; }
|
||||
void ShouldRelease(bool inRelease) { mRelease = inRelease; }
|
||||
|
||||
CFTypeID GetTypeID() const { return CFGetTypeID(mCFArray); }
|
||||
|
||||
CFArrayRef GetCFArray() const { return mCFArray; }
|
||||
CFArrayRef CopyCFArray() const { if(mCFArray != NULL) { CFRetain(mCFArray); } return mCFArray; }
|
||||
|
||||
CFMutableArrayRef GetCFMutableArray() const { return mCFArray; }
|
||||
CFMutableArrayRef CopyCFMutableArray() const { if(mCFArray != NULL) { CFRetain(mCFArray); } return mCFArray; }
|
||||
CFPropertyListRef AsPropertyList() const { return mCFArray; }
|
||||
|
||||
void SetCFMutableArrayFromCopy(CFArrayRef inArray, bool inRelease = true) { Release(); mCFArray = CFArrayCreateMutableCopy(NULL, 0, inArray); mMutable = true; mRelease = inRelease; }
|
||||
|
||||
// Item Operations
|
||||
public:
|
||||
UInt32 GetNumberItems() const { UInt32 theAnswer = 0; if(mCFArray != NULL) { theAnswer = ToUInt32(CFArrayGetCount(mCFArray)); } return theAnswer; }
|
||||
bool HasItem(const void* inItem) const;
|
||||
void RemoveItem(const void* inItem) { UInt32 theIndex; if(CanModify() && GetIndexOfItem(inItem, theIndex)) { RemoveItemAtIndex(theIndex); } }
|
||||
bool GetIndexOfItem(const void* inItem, UInt32& outIndex) const;
|
||||
void RemoveItemAtIndex(UInt32 inIndex) { if(CanModify()) { CFArrayRemoveValueAtIndex(mCFArray, static_cast<CFIndex>(inIndex)); } }
|
||||
void Clear() { if(CanModify()) { CFArrayRemoveAllValues(mCFArray); } }
|
||||
void Sort(CFComparatorFunction inCompareFunction) { if(CanModify()) { CFRange theRange = { 0, CFArrayGetCount(mCFArray) }; CFArraySortValues(mCFArray, theRange, inCompareFunction, NULL); } }
|
||||
void SortNumbers() { Sort((CFComparatorFunction)CFNumberCompare); }
|
||||
void SortStrings() { Sort((CFComparatorFunction)CFStringCompare); }
|
||||
|
||||
bool GetBool(UInt32 inIndex, bool& outValue) const;
|
||||
bool GetSInt32(UInt32 inIndex, SInt32& outItem) const;
|
||||
bool GetUInt32(UInt32 inIndex, UInt32& outItem) const;
|
||||
bool GetSInt64(UInt32 inIndex, SInt64& outItem) const;
|
||||
bool GetUInt64(UInt32 inIndex, UInt64& outItem) const;
|
||||
bool GetFloat32(UInt32 inIndex, Float32& outItem) const;
|
||||
bool GetFloat64(UInt32 inIndex, Float64& outItem) const;
|
||||
bool Get4CC(UInt32 inIndex, UInt32& outValue) const;
|
||||
bool GetString(UInt32 inIndex, CFStringRef& outItem) const;
|
||||
bool GetArray(UInt32 inIndex, CFArrayRef& outItem) const;
|
||||
bool GetDictionary(UInt32 inIndex, CFDictionaryRef& outItem) const;
|
||||
bool GetData(UInt32 inIndex, CFDataRef& outItem) const;
|
||||
bool GetUUID(UInt32 inIndex, CFUUIDRef& outItem) const;
|
||||
bool GetCFType(UInt32 inIndex, CFTypeRef& outItem) const;
|
||||
|
||||
void GetCACFString(UInt32 inIndex, CACFString& outItem) const;
|
||||
void GetCACFArray(UInt32 inIndex, CACFArray& outItem) const;
|
||||
void GetCACFDictionary(UInt32 inIndex, CACFDictionary& outItem) const;
|
||||
|
||||
bool AppendBool(bool inItem);
|
||||
bool AppendSInt32(SInt32 inItem);
|
||||
bool AppendUInt32(UInt32 inItem);
|
||||
bool AppendSInt64(SInt64 inItem);
|
||||
bool AppendUInt64(UInt64 inItem);
|
||||
bool AppendFloat32(Float32 inItem);
|
||||
bool AppendFloat64(Float64 inItem);
|
||||
bool AppendString(const CFStringRef inItem);
|
||||
bool AppendArray(const CFArrayRef inItem);
|
||||
bool AppendDictionary(const CFDictionaryRef inItem);
|
||||
bool AppendData(const CFDataRef inItem);
|
||||
bool AppendCFType(const CFTypeRef inItem);
|
||||
|
||||
bool InsertBool(UInt32 inIndex, bool inItem);
|
||||
bool InsertSInt32(UInt32 inIndex, SInt32 inItem);
|
||||
bool InsertUInt32(UInt32 inIndex, UInt32 inItem);
|
||||
bool InsertSInt64(UInt32 inIndex, SInt64 inItem);
|
||||
bool InsertUInt64(UInt32 inIndex, UInt64 inItem);
|
||||
bool InsertFloat32(UInt32 inIndex, Float32 inItem);
|
||||
bool InsertFloat64(UInt32 inIndex, Float64 inItem);
|
||||
bool InsertString(UInt32 inIndex, const CFStringRef inItem);
|
||||
bool InsertArray(UInt32 inIndex, const CFArrayRef inItem);
|
||||
bool InsertDictionary(UInt32 inIndex, const CFDictionaryRef inItem);
|
||||
bool InsertData(UInt32 inIndex, const CFDataRef inItem);
|
||||
bool InsertCFType(UInt32 inIndex, const CFTypeRef inItem);
|
||||
|
||||
bool SetBool(UInt32 inIndex, bool inItem);
|
||||
bool SetSInt32(UInt32 inIndex, SInt32 inItem);
|
||||
bool SetUInt32(UInt32 inIndex, UInt32 inItem);
|
||||
bool SetSInt64(UInt32 inIndex, SInt64 inItem);
|
||||
bool SetUInt64(UInt32 inIndex, UInt64 inItem);
|
||||
bool SetFloat32(UInt32 inIndex, Float32 inItem);
|
||||
bool SetFloat64(UInt32 inIndex, Float64 inItem);
|
||||
bool SetString(UInt32 inIndex, const CFStringRef inItem);
|
||||
bool SetArray(UInt32 inIndex, const CFArrayRef inItem);
|
||||
bool SetDictionary(UInt32 inIndex, const CFDictionaryRef inItem);
|
||||
bool SetData(UInt32 inIndex, const CFDataRef inItem);
|
||||
bool SetCFType(UInt32 inIndex, const CFTypeRef inItem);
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CFMutableArrayRef mCFArray;
|
||||
bool mRelease;
|
||||
bool mMutable;
|
||||
|
||||
CACFArray(const void*); // prevent accidental instantiation with a pointer via bool constructor
|
||||
};
|
||||
|
||||
#endif
|
||||
581
driver/PublicUtility/CACFDictionary.cpp
Normal file
581
driver/PublicUtility/CACFDictionary.cpp
Normal file
@@ -0,0 +1,581 @@
|
||||
/*
|
||||
File: CACFDictionary.cpp
|
||||
Abstract: CACFDictionary.h
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CACFDictionary.h"
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CACFArray.h"
|
||||
#include "CACFNumber.h"
|
||||
#include "CACFString.h"
|
||||
|
||||
//=============================================================================
|
||||
// CACFDictionary
|
||||
//=============================================================================
|
||||
|
||||
bool CACFDictionary::HasKey(const CFStringRef inKey) const
|
||||
{
|
||||
return CFDictionaryContainsKey(mCFDictionary, inKey) != 0;
|
||||
}
|
||||
|
||||
UInt32 CACFDictionary::Size () const
|
||||
{
|
||||
return mCFDictionary ? ToUInt32(CFDictionaryGetCount(mCFDictionary)) : 0;
|
||||
}
|
||||
|
||||
void CACFDictionary::GetKeys (const void **keys) const
|
||||
{
|
||||
CFDictionaryGetKeysAndValues(mCFDictionary, keys, NULL);
|
||||
}
|
||||
|
||||
void CACFDictionary::GetKeysAndValues (const void **keys, const void **values) const
|
||||
{
|
||||
CFDictionaryGetKeysAndValues(mCFDictionary, keys, values);
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetBool(const CFStringRef inKey, bool& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFBooleanGetTypeID()))
|
||||
{
|
||||
outValue = CFBooleanGetValue(static_cast<CFBooleanRef>(theValue));
|
||||
theAnswer = true;
|
||||
}
|
||||
else if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
SInt32 theNumericValue = 0;
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theNumericValue);
|
||||
outValue = theNumericValue != 0;
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetSInt32(const CFStringRef inKey, SInt32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetUInt32(const CFStringRef inKey, UInt32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetSInt64(const CFStringRef inKey, SInt64& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetUInt64(const CFStringRef inKey, UInt64& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetFloat32FromString(const CFStringRef inKey, Float32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<Float32>(CFStringGetDoubleValue(static_cast<CFStringRef>(theValue)));
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetUInt32FromString(const CFStringRef inKey, UInt32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
|
||||
{
|
||||
outValue = CFStringGetIntValue(static_cast<CFStringRef>(theValue));
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetFloat32(const CFStringRef inKey, Float32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetFloat64(const CFStringRef inKey, Float64& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberFloat64Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetFixed32(const CFStringRef inKey, Float32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
SInt32 theFixed32 = 0;
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &theFixed32);
|
||||
|
||||
// this is a 16.16 value so convert it to a float
|
||||
Float32 theSign = theFixed32 < 0 ? -1.0f : 1.0f;
|
||||
theFixed32 *= (SInt32)theSign;
|
||||
Float32 theWholePart = (theFixed32 & 0x7FFF0000) >> 16;
|
||||
Float32 theFractPart = theFixed32 & 0x0000FFFF;
|
||||
theFractPart /= 65536.0f;
|
||||
outValue = theSign * (theWholePart + theFractPart);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetFixed64(const CFStringRef inKey, Float64& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
SInt64 theFixed64 = 0;
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt64Type, &theFixed64);
|
||||
outValue = static_cast<Float64>(theFixed64 >> 32);
|
||||
outValue += static_cast<Float64>(theFixed64 & 0x00000000FFFFFFFFLL) / static_cast<Float64>(0x0000000100000000LL);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::Get4CC(const CFStringRef inKey, UInt32& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFNumberGetTypeID()))
|
||||
{
|
||||
CFNumberGetValue(static_cast<CFNumberRef>(theValue), kCFNumberSInt32Type, &outValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
else if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
|
||||
{
|
||||
CFStringRef theString = static_cast<CFStringRef>(theValue);
|
||||
if(CFStringGetLength(theString) == 4)
|
||||
{
|
||||
char theCString[5];
|
||||
CFStringGetCString(theString, theCString, 5, kCFStringEncodingASCII);
|
||||
outValue = CFSwapInt32BigToHost(*reinterpret_cast<UInt32*>(theCString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetString(const CFStringRef inKey, CFStringRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFStringRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetArray(const CFStringRef inKey, CFArrayRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFArrayRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFDictionaryRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetData(const CFStringRef inKey, CFDataRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFDataGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFDataRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mCFDictionary != NULL)
|
||||
{
|
||||
outValue = CFDictionaryGetValue(mCFDictionary, inKey);
|
||||
theAnswer = (outValue != NULL);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetURL(const CFStringRef inKey, CFURLRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFURLGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFURLRef>(theValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mCFDictionary != NULL)
|
||||
{
|
||||
CACFString theKey(inKey);
|
||||
if(theKey.IsValid())
|
||||
{
|
||||
theAnswer = GetCFType(theKey.GetCFString(), outValue);
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CACFDictionary::GetCACFString(const CFStringRef inKey, CACFString& outValue) const
|
||||
{
|
||||
outValue = static_cast<CFStringRef>(NULL);
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFStringGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFStringRef>(theValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CACFDictionary::GetCACFArray(const CFStringRef inKey, CACFArray& outValue) const
|
||||
{
|
||||
outValue = static_cast<CFArrayRef>(NULL);
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFArrayGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFArrayRef>(theValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CACFDictionary::GetCACFDictionary(const CFStringRef inKey, CACFDictionary& outValue) const
|
||||
{
|
||||
outValue = static_cast<CFDictionaryRef>(NULL);
|
||||
CFTypeRef theValue = NULL;
|
||||
if(GetCFType(inKey, theValue))
|
||||
{
|
||||
if((theValue != NULL) && (CFGetTypeID(theValue) == CFDictionaryGetTypeID()))
|
||||
{
|
||||
outValue = static_cast<CFDictionaryRef>(theValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddBool(const CFStringRef inKey, bool inValue)
|
||||
{
|
||||
CACFBoolean theValue(inValue);
|
||||
return AddCFType(inKey, theValue.GetCFBoolean());
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddSInt32(const CFStringRef inKey, SInt32 inValue)
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
return AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddUInt32(const CFStringRef inKey, UInt32 inValue)
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
return AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddSInt64(const CFStringRef inKey, SInt64 inValue)
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
return AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddUInt64(const CFStringRef inKey, UInt64 inValue)
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
return AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddFloat32(const CFStringRef inKey, Float32 inValue)
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
return AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddFloat64(const CFStringRef inKey, Float64 inValue)
|
||||
{
|
||||
CACFNumber theValue(inValue);
|
||||
return AddCFType(inKey, theValue.GetCFNumber());
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddNumber(const CFStringRef inKey, const CFNumberRef inValue)
|
||||
{
|
||||
return AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddString(const CFStringRef inKey, const CFStringRef inValue)
|
||||
{
|
||||
return AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddArray(const CFStringRef inKey, const CFArrayRef inValue)
|
||||
{
|
||||
return AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue)
|
||||
{
|
||||
return AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddData(const CFStringRef inKey, const CFDataRef inValue)
|
||||
{
|
||||
return AddCFType(inKey, inValue);
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddURL(const CFStringRef inKey, const CFURLRef inValue)
|
||||
{
|
||||
return AddCFType (inKey, inValue);
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if (inKey)
|
||||
{
|
||||
CACFString theKey(inKey);
|
||||
if(theKey.IsValid())
|
||||
{
|
||||
theAnswer = AddCFType(theKey.GetCFString(), inValue);
|
||||
}
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddCString(const CFStringRef inKey, const char* inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if (inValue)
|
||||
{
|
||||
CACFString theValue(inValue);
|
||||
if(theValue.IsValid())
|
||||
{
|
||||
theAnswer = AddCFType(inKey, theValue.GetCFString());
|
||||
}
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CACFDictionary::AddCFType(const CFStringRef inKey, const CFTypeRef inValue)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
if(mMutable && (mCFDictionary != NULL) && inValue)
|
||||
{
|
||||
CFDictionarySetValue(mCFDictionary, inKey, inValue);
|
||||
theAnswer = true;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
176
driver/PublicUtility/CACFDictionary.h
Normal file
176
driver/PublicUtility/CACFDictionary.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
File: CACFDictionary.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CACFDictionary_h__)
|
||||
#define __CACFDictionary_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#else
|
||||
#include <CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Types
|
||||
//=============================================================================
|
||||
|
||||
class CACFArray;
|
||||
class CACFString;
|
||||
|
||||
//=============================================================================
|
||||
// CACFDictionary
|
||||
//=============================================================================
|
||||
|
||||
class CACFDictionary
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFDictionary() : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(true), mMutable(true) {}
|
||||
explicit CACFDictionary(bool inRelease) : mCFDictionary(CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)), mRelease(inRelease), mMutable(true) {}
|
||||
CACFDictionary(CFDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(const_cast<CFMutableDictionaryRef>(inCFDictionary)), mRelease(inRelease), mMutable(false) {}
|
||||
CACFDictionary(CFMutableDictionaryRef inCFDictionary, bool inRelease) : mCFDictionary(inCFDictionary), mRelease(inRelease), mMutable(true) {}
|
||||
CACFDictionary(const CACFDictionary& inDictionary) : mCFDictionary(inDictionary.mCFDictionary), mRelease(inDictionary.mRelease), mMutable(inDictionary.mMutable) { Retain(); }
|
||||
CACFDictionary& operator=(const CACFDictionary& inDictionary) { Release(); mCFDictionary = inDictionary.mCFDictionary; mRelease = inDictionary.mRelease; mMutable = inDictionary.mMutable; Retain(); return *this; }
|
||||
CACFDictionary& operator=(CFDictionaryRef inDictionary) { Release(); mCFDictionary = const_cast<CFMutableDictionaryRef>(inDictionary); mMutable = false; Retain(); return *this; }
|
||||
CACFDictionary& operator=(CFMutableDictionaryRef inDictionary) { Release(); mCFDictionary = inDictionary; mMutable = true; Retain(); return *this; }
|
||||
~CACFDictionary() { Release(); }
|
||||
|
||||
private:
|
||||
void Retain() { if(mRelease && (mCFDictionary != NULL)) { CFRetain(mCFDictionary); } }
|
||||
void Release() { if(mRelease && (mCFDictionary != NULL)) { CFRelease(mCFDictionary); } }
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
bool IsValid() const { return mCFDictionary != NULL; }
|
||||
bool IsMutable() const { return mMutable;}
|
||||
bool CanModify() const { return mMutable && (mCFDictionary != NULL); }
|
||||
|
||||
bool WillRelease() const { return mRelease; }
|
||||
void ShouldRelease(bool inRelease) { mRelease = inRelease; }
|
||||
|
||||
CFDictionaryRef GetDict() const { return mCFDictionary; }
|
||||
CFDictionaryRef GetCFDictionary() const { return mCFDictionary; }
|
||||
CFDictionaryRef CopyCFDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
|
||||
|
||||
CFMutableDictionaryRef GetMutableDict() { return mCFDictionary; }
|
||||
CFMutableDictionaryRef GetCFMutableDictionary() const { return mCFDictionary; }
|
||||
CFMutableDictionaryRef CopyCFMutableDictionary() const { if(mCFDictionary != NULL) { CFRetain(mCFDictionary); } return mCFDictionary; }
|
||||
void SetCFMutableDictionaryFromCopy(CFDictionaryRef inDictionary, bool inRelease = true) { Release(); mCFDictionary = CFDictionaryCreateMutableCopy(NULL, 0, inDictionary); mMutable = true; mRelease = inRelease; }
|
||||
void SetCFMutableDictionaryToEmpty(bool inRelease = true) { Release(); mCFDictionary = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); mMutable = true; mRelease = inRelease; }
|
||||
|
||||
CFPropertyListRef AsPropertyList() const { return mCFDictionary; }
|
||||
OSStatus GetDictIfMutable(CFMutableDictionaryRef& outDict) const { OSStatus theAnswer = -1; if(mMutable) { outDict = mCFDictionary; theAnswer = 0; } return theAnswer; }
|
||||
|
||||
// Item Operations
|
||||
public:
|
||||
bool HasKey(const CFStringRef inKey) const;
|
||||
UInt32 Size() const;
|
||||
void GetKeys(const void** keys) const;
|
||||
void GetKeysAndValues (const void **keys, const void **values) const;
|
||||
|
||||
bool GetBool(const CFStringRef inKey, bool& outValue) const;
|
||||
bool GetSInt32(const CFStringRef inKey, SInt32& outValue) const;
|
||||
bool GetUInt32(const CFStringRef inKey, UInt32& outValue) const;
|
||||
bool GetUInt32FromString(const CFStringRef inKey, UInt32& outValue) const;
|
||||
bool GetSInt64(const CFStringRef inKey, SInt64& outValue) const;
|
||||
bool GetUInt64(const CFStringRef inKey, UInt64& outValue) const;
|
||||
bool GetFloat32(const CFStringRef inKey, Float32& outValue) const;
|
||||
bool GetFloat32FromString(const CFStringRef inKey, Float32& outValue) const;
|
||||
bool GetFloat64(const CFStringRef inKey, Float64& outValue) const;
|
||||
bool GetFixed32(const CFStringRef inKey, Float32& outValue) const;
|
||||
bool GetFixed64(const CFStringRef inKey, Float64& outValue) const;
|
||||
bool Get4CC(const CFStringRef inKey, UInt32& outValue) const;
|
||||
bool GetString(const CFStringRef inKey, CFStringRef& outValue) const;
|
||||
bool GetArray(const CFStringRef inKey, CFArrayRef& outValue) const;
|
||||
bool GetDictionary(const CFStringRef inKey, CFDictionaryRef& outValue) const;
|
||||
bool GetData(const CFStringRef inKey, CFDataRef& outValue) const;
|
||||
bool GetCFType(const CFStringRef inKey, CFTypeRef& outValue) const;
|
||||
bool GetURL(const CFStringRef inKey, CFURLRef& outValue) const;
|
||||
bool GetCFTypeWithCStringKey(const char* inKey, CFTypeRef& outValue) const;
|
||||
|
||||
void GetCACFString(const CFStringRef inKey, CACFString& outItem) const;
|
||||
void GetCACFArray(const CFStringRef inKey, CACFArray& outItem) const;
|
||||
void GetCACFDictionary(const CFStringRef inKey, CACFDictionary& outItem) const;
|
||||
|
||||
bool AddBool(const CFStringRef inKey, bool inValue);
|
||||
bool AddSInt32(const CFStringRef inKey, SInt32 inValue);
|
||||
bool AddUInt32(const CFStringRef inKey, UInt32 inValue);
|
||||
bool AddSInt64(const CFStringRef inKey, SInt64 inValue);
|
||||
bool AddUInt64(const CFStringRef inKey, UInt64 inValue);
|
||||
bool AddFloat32(const CFStringRef inKey, Float32 inValue);
|
||||
bool AddFloat64(const CFStringRef inKey, Float64 inValue);
|
||||
bool AddNumber(const CFStringRef inKey, const CFNumberRef inValue);
|
||||
bool AddString(const CFStringRef inKey, const CFStringRef inValue);
|
||||
bool AddArray(const CFStringRef inKey, const CFArrayRef inValue);
|
||||
bool AddDictionary(const CFStringRef inKey, const CFDictionaryRef inValue);
|
||||
bool AddData(const CFStringRef inKey, const CFDataRef inValue);
|
||||
bool AddCFType(const CFStringRef inKey, const CFTypeRef inValue);
|
||||
bool AddURL(const CFStringRef inKey, const CFURLRef inValue);
|
||||
|
||||
bool AddCFTypeWithCStringKey(const char* inKey, const CFTypeRef inValue);
|
||||
bool AddCString(const CFStringRef inKey, const char* inValue);
|
||||
|
||||
void RemoveKey(const CFStringRef inKey) { if(CanModify()) { CFDictionaryRemoveValue(mCFDictionary, inKey); } }
|
||||
void Clear() { if(CanModify()) { CFDictionaryRemoveAllValues(mCFDictionary); } }
|
||||
|
||||
void Show() { CFShow(mCFDictionary); }
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CFMutableDictionaryRef mCFDictionary;
|
||||
bool mRelease;
|
||||
bool mMutable;
|
||||
|
||||
CACFDictionary(const void*); // prevent accidental instantiation with a pointer via bool constructor
|
||||
};
|
||||
|
||||
#endif //__CACFDictionary_h__
|
||||
83
driver/PublicUtility/CACFNumber.cpp
Normal file
83
driver/PublicUtility/CACFNumber.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
File: CACFNumber.cpp
|
||||
Abstract: CACFNumber.h
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CACFNumber.h"
|
||||
|
||||
//=============================================================================
|
||||
// CACFNumber
|
||||
//=============================================================================
|
||||
|
||||
Float32 CACFNumber::GetFixed32() const
|
||||
{
|
||||
SInt32 theFixedValue = GetSInt32();
|
||||
|
||||
// this is a 16.16 value so convert it to a float
|
||||
Float32 theSign = theFixedValue < 0 ? -1.0f : 1.0f;
|
||||
theFixedValue *= (SInt32)theSign;
|
||||
Float32 theWholePart = (theFixedValue & 0x7FFF0000) >> 16;
|
||||
Float32 theFractPart = theFixedValue & 0x0000FFFF;
|
||||
theFractPart /= 65536.0f;
|
||||
|
||||
return theSign * (theWholePart + theFractPart);
|
||||
}
|
||||
|
||||
Float64 CACFNumber::GetFixed64() const
|
||||
{
|
||||
SInt64 theFixedValue = GetSInt64();
|
||||
|
||||
// this is a 32.32 value so convert it to a double
|
||||
Float64 theSign = theFixedValue < 0 ? -1.0 : 1.0;
|
||||
theFixedValue *= (SInt64)theSign;
|
||||
Float64 theWholePart = (theFixedValue & 0x7FFFFFFF00000000LL) >> 32;
|
||||
Float64 theFractPart = theFixedValue & 0x00000000FFFFFFFFLL;
|
||||
theFractPart /= 4294967296.0;
|
||||
|
||||
return theSign * (theWholePart + theFractPart);
|
||||
}
|
||||
151
driver/PublicUtility/CACFNumber.h
Normal file
151
driver/PublicUtility/CACFNumber.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
File: CACFNumber.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CACFNumber_h__)
|
||||
#define __CACFNumber_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CFNumber.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CFNumber.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CACFBoolean
|
||||
//=============================================================================
|
||||
|
||||
class CACFBoolean
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
explicit CACFBoolean(CFBooleanRef inCFBoolean) : mCFBoolean(inCFBoolean), mWillRelease(true) {}
|
||||
CACFBoolean(CFBooleanRef inCFBoolean, bool inWillRelease) : mCFBoolean(inCFBoolean), mWillRelease(inWillRelease) {}
|
||||
explicit CACFBoolean(bool inValue) : mCFBoolean(inValue ? kCFBooleanTrue : kCFBooleanFalse), mWillRelease(true) { Retain(); }
|
||||
~CACFBoolean() { Release(); }
|
||||
CACFBoolean(const CACFBoolean& inBoolean) : mCFBoolean(inBoolean.mCFBoolean), mWillRelease(inBoolean.mWillRelease) { Retain(); }
|
||||
CACFBoolean& operator=(const CACFBoolean& inBoolean) { Release(); mCFBoolean = inBoolean.mCFBoolean; mWillRelease = inBoolean.mWillRelease; Retain(); return *this; }
|
||||
CACFBoolean& operator=(CFBooleanRef inCFBoolean) { Release(); mCFBoolean = inCFBoolean; mWillRelease = true; return *this; }
|
||||
|
||||
private:
|
||||
void Retain() { if(mWillRelease && (mCFBoolean != NULL)) { CFRetain(mCFBoolean); } }
|
||||
void Release() { if(mWillRelease && (mCFBoolean != NULL)) { CFRelease(mCFBoolean); } }
|
||||
|
||||
CFBooleanRef mCFBoolean;
|
||||
bool mWillRelease;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AllowRelease() { mWillRelease = true; }
|
||||
void DontAllowRelease() { mWillRelease = false; }
|
||||
bool IsValid() { return mCFBoolean != NULL; }
|
||||
|
||||
// Value Access
|
||||
public:
|
||||
CFBooleanRef GetCFBoolean() const { return mCFBoolean; }
|
||||
CFBooleanRef CopyCFBoolean() const { if(mCFBoolean != NULL) { CFRetain(mCFBoolean); } return mCFBoolean; }
|
||||
|
||||
bool GetBoolean() const { bool theAnswer = false; if(mCFBoolean != NULL) { theAnswer = CFEqual(mCFBoolean, kCFBooleanTrue); } return theAnswer; }
|
||||
|
||||
CACFBoolean(const void*); // prevent accidental instantiation with a pointer via bool constructor
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// CACFNumber
|
||||
//=============================================================================
|
||||
|
||||
class CACFNumber
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
explicit CACFNumber(CFNumberRef inCFNumber) : mCFNumber(inCFNumber), mWillRelease(true) {}
|
||||
CACFNumber(CFNumberRef inCFNumber, bool inWillRelease) : mCFNumber(inCFNumber), mWillRelease(inWillRelease) {}
|
||||
CACFNumber(SInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(UInt32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt32Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(SInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(UInt64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberSInt64Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(Float32 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat32Type, &inValue)), mWillRelease(true) {}
|
||||
CACFNumber(Float64 inValue) : mCFNumber(CFNumberCreate(NULL, kCFNumberFloat64Type, &inValue)), mWillRelease(true) {}
|
||||
~CACFNumber() { Release(); }
|
||||
CACFNumber(const CACFNumber& inNumber) : mCFNumber(inNumber.mCFNumber), mWillRelease(inNumber.mWillRelease) { Retain(); }
|
||||
CACFNumber& operator=(const CACFNumber& inNumber) { Release(); mCFNumber = inNumber.mCFNumber; mWillRelease = inNumber.mWillRelease; Retain(); return *this; }
|
||||
CACFNumber& operator=(CFNumberRef inCFNumber) { Release(); mCFNumber = inCFNumber; mWillRelease = true; return *this; }
|
||||
|
||||
private:
|
||||
void Retain() { if(mWillRelease && (mCFNumber != NULL)) { CFRetain(mCFNumber); } }
|
||||
void Release() { if(mWillRelease && (mCFNumber != NULL)) { CFRelease(mCFNumber); } }
|
||||
|
||||
CFNumberRef mCFNumber;
|
||||
bool mWillRelease;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AllowRelease() { mWillRelease = true; }
|
||||
void DontAllowRelease() { mWillRelease = false; }
|
||||
bool IsValid() const { return mCFNumber != NULL; }
|
||||
|
||||
// Value Access
|
||||
public:
|
||||
CFNumberRef GetCFNumber() const { return mCFNumber; }
|
||||
CFNumberRef CopyCFNumber() const { if(mCFNumber != NULL) { CFRetain(mCFNumber); } return mCFNumber; }
|
||||
|
||||
SInt8 GetSInt8() const { SInt8 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt8Type, &theAnswer); } return theAnswer; }
|
||||
SInt32 GetSInt32() const { SInt32 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt32Type, &theAnswer); } return theAnswer; }
|
||||
UInt32 GetUInt32() const { UInt32 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt32Type, &theAnswer); } return theAnswer; }
|
||||
Float32 GetFloat32() const { Float32 theAnswer = 0.0f; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberFloat32Type, &theAnswer); } return theAnswer; }
|
||||
Float32 GetFixed32() const;
|
||||
Float64 GetFixed64() const;
|
||||
SInt64 GetSInt64() const { SInt64 theAnswer = 0; if(mCFNumber != NULL) { CFNumberGetValue(mCFNumber, kCFNumberSInt64Type, &theAnswer); } return theAnswer; }
|
||||
|
||||
CACFNumber(const void*); // prevent accidental instantiation with a pointer via bool constructor
|
||||
};
|
||||
|
||||
#endif
|
||||
110
driver/PublicUtility/CACFString.cpp
Normal file
110
driver/PublicUtility/CACFString.cpp
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
File: CACFString.cpp
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CACFString.h"
|
||||
|
||||
//=============================================================================
|
||||
// CACFString
|
||||
//=============================================================================
|
||||
|
||||
UInt32 CACFString::GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding)
|
||||
{
|
||||
CFIndex theAnswer = 0;
|
||||
|
||||
if(inCFString != NULL)
|
||||
{
|
||||
CFRange theRange = { 0, CFStringGetLength(inCFString) };
|
||||
CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, NULL, 0x7FFFFFFF, &theAnswer);
|
||||
}
|
||||
|
||||
return UInt32(theAnswer);
|
||||
}
|
||||
|
||||
void CACFString::GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding)
|
||||
{
|
||||
if(ioStringSize > 0)
|
||||
{
|
||||
if(inCFString != NULL)
|
||||
{
|
||||
CFIndex theLength = 0;
|
||||
CFRange theRange = { 0, CFStringGetLength(inCFString) };
|
||||
CFStringGetBytes(inCFString, theRange, inEncoding, 0, false, (UInt8*)outString, static_cast<CFIndex>(ioStringSize - 1), &theLength);
|
||||
outString[theLength] = 0;
|
||||
ioStringSize = ToUInt32(theLength) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
outString[0] = 0;
|
||||
ioStringSize = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CACFString::GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize)
|
||||
{
|
||||
if(ioStringSize > 0)
|
||||
{
|
||||
if(inCFString != NULL)
|
||||
{
|
||||
CFRange theStringRange = { 0, CFStringGetLength(inCFString) };
|
||||
if(static_cast<UInt32>(theStringRange.length) > ioStringSize)
|
||||
{
|
||||
theStringRange.length = static_cast<CFIndex>(ioStringSize);
|
||||
}
|
||||
CFStringGetCharacters(inCFString, theStringRange, outString);
|
||||
ioStringSize = ToUInt32(theStringRange.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
outString[0] = 0;
|
||||
ioStringSize = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
180
driver/PublicUtility/CACFString.h
Normal file
180
driver/PublicUtility/CACFString.h
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
File: CACFString.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CACFString_h__)
|
||||
#define __CACFString_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CADebugMacros.h"
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#include <CFString.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CACFString
|
||||
//
|
||||
// Notes
|
||||
// - Using the AssignWithoutRetain() method will fool the static analyzer into thinking that the
|
||||
// CFString being assigned will be leaked. This is because the static analyzer is not smart
|
||||
// enough to understand that the destructor will release the object.
|
||||
//=============================================================================
|
||||
|
||||
class CACFString
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFString() : mCFString(NULL), mWillRelease(true) {}
|
||||
CACFString(CFStringRef inCFString, bool inWillRelease = true) : mCFString(inCFString), mWillRelease(inWillRelease) {}
|
||||
CACFString(const char* inCString, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, kCFStringEncodingASCII)), mWillRelease(inWillRelease) {}
|
||||
CACFString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFString(CFStringCreateWithCString(NULL, inCString, inCStringEncoding)), mWillRelease(inWillRelease) {}
|
||||
~CACFString() { Release(); }
|
||||
CACFString(const CACFString& inString) : mCFString(inString.mCFString), mWillRelease(inString.mWillRelease) { Retain(); }
|
||||
CACFString& operator=(const CACFString& inString) { if (inString.mCFString != mCFString) { Release(); mCFString = inString.mCFString; mWillRelease = inString.mWillRelease; Retain(); } return *this; }
|
||||
CACFString& operator=(CFStringRef inCFString) { if (inCFString != mCFString) { Release(); mCFString = inCFString; } mWillRelease = true; Retain(); return *this; }
|
||||
void AssignWithoutRetain(CFStringRef inCFString) { if (inCFString != mCFString) { Release(); mCFString = inCFString; } mWillRelease = true; }
|
||||
|
||||
private:
|
||||
void Retain() { if(mWillRelease && (mCFString != NULL)) { CFRetain(mCFString); } }
|
||||
void Release() { if(mWillRelease && (mCFString != NULL)) { CFRelease(mCFString); } }
|
||||
|
||||
CFStringRef mCFString;
|
||||
bool mWillRelease;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AllowRelease() { mWillRelease = true; }
|
||||
void DontAllowRelease() { mWillRelease = false; }
|
||||
bool IsValid() const { return mCFString != NULL; }
|
||||
bool IsEqualTo(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringCompare(inString, mCFString, 0) == kCFCompareEqualTo; } return theAnswer; }
|
||||
bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasPrefix(mCFString, inString); } return theAnswer; }
|
||||
bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFString != NULL) { theAnswer = CFStringHasSuffix(mCFString, inString); } return theAnswer; }
|
||||
|
||||
// Value Access
|
||||
public:
|
||||
CFStringRef GetCFString() const { return mCFString; }
|
||||
CFStringRef CopyCFString() const { if(mCFString != NULL) { CFRetain(mCFString); } return mCFString; }
|
||||
const CFStringRef* GetPointerToStorage() const { return &mCFString; }
|
||||
CFStringRef& GetStorage() { Release(); mWillRelease = true; return mCFString; }
|
||||
UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = ToUInt32(CFStringGetLength(mCFString)); } return theAnswer; }
|
||||
UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFString != NULL) { theAnswer = GetStringByteLength(mCFString, inEncoding); } return theAnswer; }
|
||||
void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { GetCString(mCFString, outString, ioStringSize, inEncoding); }
|
||||
void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { GetUnicodeString(mCFString, outString, ioStringSize); }
|
||||
SInt32 GetAsInteger() { return GetAsInteger(mCFString); }
|
||||
Float64 GetAsFloat64() { return GetAsFloat64(mCFString); }
|
||||
|
||||
static UInt32 GetStringLength(CFStringRef inCFString) { UInt32 theAnswer = 0; if(inCFString != NULL) { theAnswer = ToUInt32(CFStringGetLength(inCFString)); } return theAnswer; }
|
||||
static UInt32 GetStringByteLength(CFStringRef inCFString, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
|
||||
static void GetCString(CFStringRef inCFString, char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8);
|
||||
static void GetUnicodeString(CFStringRef inCFString, UInt16* outString, UInt32& ioStringSize);
|
||||
static SInt32 GetAsInteger(CFStringRef inCFString) { SInt32 theAnswer = 0; if(inCFString != NULL){ theAnswer = CFStringGetIntValue(inCFString); } return theAnswer; }
|
||||
static Float64 GetAsFloat64(CFStringRef inCFString) { Float64 theAnswer = 0; if(inCFString != NULL){ theAnswer = CFStringGetDoubleValue(inCFString); } return theAnswer; }
|
||||
|
||||
};
|
||||
|
||||
inline bool operator<(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareLessThan; }
|
||||
inline bool operator==(const CACFString& x, const CACFString& y) { return CFStringCompare(x.GetCFString(), y.GetCFString(), 0) == kCFCompareEqualTo; }
|
||||
inline bool operator!=(const CACFString& x, const CACFString& y) { return !(x == y); }
|
||||
inline bool operator<=(const CACFString& x, const CACFString& y) { return (x < y) || (x == y); }
|
||||
inline bool operator>=(const CACFString& x, const CACFString& y) { return !(x < y); }
|
||||
inline bool operator>(const CACFString& x, const CACFString& y) { return !((x < y) || (x == y)); }
|
||||
|
||||
//=============================================================================
|
||||
// CACFMutableString
|
||||
//=============================================================================
|
||||
|
||||
class CACFMutableString
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CACFMutableString() : mCFMutableString(NULL), mWillRelease(true) {}
|
||||
CACFMutableString(CFMutableStringRef inCFMutableString, bool inWillRelease = true) : mCFMutableString(inCFMutableString), mWillRelease(inWillRelease) {}
|
||||
CACFMutableString(CFStringRef inStringToCopy, bool /*inMakeCopy*/, bool inWillRelease = true) : mCFMutableString(CFStringCreateMutableCopy(NULL, 0, inStringToCopy)), mWillRelease(inWillRelease) {}
|
||||
CACFMutableString(const char* inCString, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
|
||||
CACFMutableString(const char* inCString, CFStringEncoding inCStringEncoding, bool inWillRelease = true) : mCFMutableString(NULL), mWillRelease(inWillRelease) { CACFString theString(inCString, inCStringEncoding); mCFMutableString = CFStringCreateMutableCopy(NULL, 0, theString.GetCFString()); }
|
||||
~CACFMutableString() { Release(); }
|
||||
CACFMutableString(const CACFMutableString& inString) : mCFMutableString(inString.mCFMutableString), mWillRelease(inString.mWillRelease) { Retain(); }
|
||||
CACFMutableString& operator=(const CACFMutableString& inString) { Release(); mCFMutableString = inString.mCFMutableString; mWillRelease = inString.mWillRelease; Retain(); return *this; }
|
||||
CACFMutableString& operator=(CFMutableStringRef inCFMutableString) { Release(); mCFMutableString = inCFMutableString; mWillRelease = true; return *this; }
|
||||
|
||||
private:
|
||||
void Retain() { if(mWillRelease && (mCFMutableString != NULL)) { CFRetain(mCFMutableString); } }
|
||||
void Release() { if(mWillRelease && (mCFMutableString != NULL)) { CFRelease(mCFMutableString); } }
|
||||
|
||||
CFMutableStringRef mCFMutableString;
|
||||
bool mWillRelease;
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AllowRelease() { mWillRelease = true; }
|
||||
void DontAllowRelease() { mWillRelease = false; }
|
||||
bool IsValid() { return mCFMutableString != NULL; }
|
||||
bool IsEqualTo(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringCompare(inString, mCFMutableString, 0) == kCFCompareEqualTo; } return theAnswer; }
|
||||
bool StartsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasPrefix(mCFMutableString, inString); } return theAnswer; }
|
||||
bool EndsWith(CFStringRef inString) const { bool theAnswer = false; if(mCFMutableString != NULL) { theAnswer = CFStringHasSuffix(mCFMutableString, inString); } return theAnswer; }
|
||||
void Append(CFStringRef inString) { if(mCFMutableString != NULL) { CFStringAppend(mCFMutableString, inString); } }
|
||||
|
||||
// Value Access
|
||||
public:
|
||||
CFMutableStringRef GetCFMutableString() const { return mCFMutableString; }
|
||||
CFMutableStringRef CopyCFMutableString() const { if(mCFMutableString != NULL) { CFRetain(mCFMutableString); } return mCFMutableString; }
|
||||
UInt32 GetLength() const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = ToUInt32(CFStringGetLength(mCFMutableString)); } return theAnswer; }
|
||||
UInt32 GetByteLength(CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { UInt32 theAnswer = 0; if(mCFMutableString != NULL) { theAnswer = CACFString::GetStringByteLength(mCFMutableString, inEncoding); } return theAnswer; }
|
||||
void GetCString(char* outString, UInt32& ioStringSize, CFStringEncoding inEncoding = kCFStringEncodingUTF8) const { CACFString::GetCString(mCFMutableString, outString, ioStringSize, inEncoding); }
|
||||
void GetUnicodeString(UInt16* outString, UInt32& ioStringSize) const { CACFString::GetUnicodeString(mCFMutableString, outString, ioStringSize); }
|
||||
SInt32 GetAsInteger() { return CACFString::GetAsInteger(mCFMutableString); }
|
||||
Float64 GetAsFloat64() { return CACFString::GetAsFloat64(mCFMutableString); }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
116
driver/PublicUtility/CADebugMacros.cpp
Normal file
116
driver/PublicUtility/CADebugMacros.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
File: CADebugMacros.cpp
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "CADebugMacros.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#if TARGET_API_MAC_OSX
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
|
||||
void DebugPrint(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
void LogError(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
// VC edit: vprintf leaves args in an undefined state, which can cause a crash in
|
||||
// vsyslog. Also added __ASSERT_STOP. Original code commented out below.
|
||||
//#if DEBUG
|
||||
// vprintf(fmt, args);
|
||||
//#endif
|
||||
//#if TARGET_API_MAC_OSX
|
||||
// vsyslog(LOG_ERR, fmt, args);
|
||||
//#endif
|
||||
#if (DEBUG || !TARGET_API_MAC_OSX) && !CoreAudio_UseSysLog
|
||||
printf("[ERROR] ");
|
||||
vprintf(fmt, args);
|
||||
printf("\n");
|
||||
#else
|
||||
vsyslog(LOG_ERR, fmt, args);
|
||||
#endif
|
||||
#if DEBUG
|
||||
__ASSERT_STOP;
|
||||
#endif
|
||||
// VC edit end
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void LogWarning(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
// VC edit: vprintf leaves args in an undefined state, which can cause a crash in
|
||||
// vsyslog. Also added __ASSERT_STOP. Original code commented out below.
|
||||
//#if DEBUG
|
||||
// vprintf(fmt, args);
|
||||
//#endif
|
||||
//#if TARGET_API_MAC_OSX
|
||||
// vsyslog(LOG_WARNING, fmt, args);
|
||||
//#endif
|
||||
#if (DEBUG || !TARGET_API_MAC_OSX) && !CoreAudio_UseSysLog
|
||||
printf("[WARNING] ");
|
||||
vprintf(fmt, args);
|
||||
printf("\n");
|
||||
#else
|
||||
vsyslog(LOG_WARNING, fmt, args);
|
||||
#endif
|
||||
#if DEBUG
|
||||
//__ASSERT_STOP; // TODO: Add a toggle for this to the project file (under "Preprocessor Macros"). Default to off.
|
||||
#endif
|
||||
// VC edit end
|
||||
va_end(args);
|
||||
}
|
||||
583
driver/PublicUtility/CADebugMacros.h
Normal file
583
driver/PublicUtility/CADebugMacros.h
Normal file
@@ -0,0 +1,583 @@
|
||||
/*
|
||||
File: CADebugMacros.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CADebugMacros_h__)
|
||||
#define __CADebugMacros_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CADebugMacros
|
||||
//=============================================================================
|
||||
|
||||
//#define CoreAudio_StopOnFailure 1
|
||||
//#define CoreAudio_TimeStampMessages 1
|
||||
//#define CoreAudio_ThreadStampMessages 1
|
||||
//#define CoreAudio_FlushDebugMessages 1
|
||||
|
||||
#if TARGET_RT_BIG_ENDIAN
|
||||
#define CA4CCToCString(the4CC) { ((char*)&the4CC)[0], ((char*)&the4CC)[1], ((char*)&the4CC)[2], ((char*)&the4CC)[3], 0 }
|
||||
#define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[0]; theCString[1] = ((char*)&the4CC)[1]; theCString[2] = ((char*)&the4CC)[2]; theCString[3] = ((char*)&the4CC)[3]; theCString[4] = 0; }
|
||||
#else
|
||||
#define CA4CCToCString(the4CC) { ((char*)&the4CC)[3], ((char*)&the4CC)[2], ((char*)&the4CC)[1], ((char*)&the4CC)[0], 0 }
|
||||
#define CACopy4CCToCString(theCString, the4CC) { theCString[0] = ((char*)&the4CC)[3]; theCString[1] = ((char*)&the4CC)[2]; theCString[2] = ((char*)&the4CC)[1]; theCString[3] = ((char*)&the4CC)[0]; theCString[4] = 0; }
|
||||
#endif
|
||||
|
||||
// This is a macro that does a sizeof and casts the result to a UInt32. This is useful for all the
|
||||
// places where -wshorten64-32 catches assigning a sizeof expression to a UInt32.
|
||||
// For want of a better place to park this, we'll park it here.
|
||||
#define SizeOf32(X) ((UInt32)sizeof(X))
|
||||
|
||||
// This is a macro that does a offsetof and casts the result to a UInt32. This is useful for all the
|
||||
// places where -wshorten64-32 catches assigning an offsetof expression to a UInt32.
|
||||
// For want of a better place to park this, we'll park it here.
|
||||
#define OffsetOf32(X, Y) ((UInt32)offsetof(X, Y))
|
||||
|
||||
// This macro casts the expression to a UInt32. It is called out specially to allow us to track casts
|
||||
// that have been added purely to avert -wshorten64-32 warnings on 64 bit platforms.
|
||||
// For want of a better place to park this, we'll park it here.
|
||||
#define ToUInt32(X) ((UInt32)(X))
|
||||
#define ToSInt32(X) ((SInt32)(X))
|
||||
|
||||
#pragma mark Basic Definitions
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
// can be used to break into debugger immediately, also see CADebugger
|
||||
#define BusError() { long* p=NULL; *p=0; }
|
||||
|
||||
// basic debugging print routines
|
||||
#if TARGET_OS_MAC && !TARGET_API_MAC_CARBON
|
||||
extern void DebugStr(const unsigned char* debuggerMsg);
|
||||
#define DebugMessage(msg) DebugStr("\p"msg)
|
||||
#define DebugMessageN1(msg, N1)
|
||||
#define DebugMessageN2(msg, N1, N2)
|
||||
#define DebugMessageN3(msg, N1, N2, N3)
|
||||
#else
|
||||
#include "CADebugPrintf.h"
|
||||
|
||||
#if (CoreAudio_FlushDebugMessages && !CoreAudio_UseSysLog) || defined(CoreAudio_UseSideFile)
|
||||
#define FlushRtn ,fflush(DebugPrintfFile)
|
||||
#else
|
||||
#define FlushRtn
|
||||
#endif
|
||||
|
||||
#if CoreAudio_ThreadStampMessages
|
||||
#include <pthread.h>
|
||||
#include "CAHostTimeBase.h"
|
||||
#if TARGET_RT_64_BIT
|
||||
#define DebugPrintfThreadIDFormat "%16p"
|
||||
#else
|
||||
#define DebugPrintfThreadIDFormat "%8p"
|
||||
#endif
|
||||
#define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " DebugPrintfThreadIDFormat " " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), pthread_self(), ## __VA_ARGS__) FlushRtn
|
||||
#elif CoreAudio_TimeStampMessages
|
||||
#include "CAHostTimeBase.h"
|
||||
#define DebugMsg(inFormat, ...) DebugPrintf("%17qd: " inFormat, CAHostTimeBase::GetCurrentTimeInNanos(), ## __VA_ARGS__) FlushRtn
|
||||
#else
|
||||
#define DebugMsg(inFormat, ...) DebugPrintf(inFormat, ## __VA_ARGS__) FlushRtn
|
||||
#endif
|
||||
#endif
|
||||
void DebugPrint(const char *fmt, ...); // can be used like printf
|
||||
#ifndef DEBUGPRINT
|
||||
#define DEBUGPRINT(msg) DebugPrint msg // have to double-parenthesize arglist (see Debugging.h)
|
||||
#endif
|
||||
#if VERBOSE
|
||||
#define vprint(msg) DEBUGPRINT(msg)
|
||||
#else
|
||||
#define vprint(msg)
|
||||
#endif
|
||||
|
||||
// Original macro keeps its function of turning on and off use of CADebuggerStop() for both asserts and throws.
|
||||
// For backwards compat, it overrides any setting of the two sub-macros.
|
||||
#if CoreAudio_StopOnFailure
|
||||
#include "CADebugger.h"
|
||||
#undef CoreAudio_StopOnAssert
|
||||
#define CoreAudio_StopOnAssert 1
|
||||
#undef CoreAudio_StopOnThrow
|
||||
#define CoreAudio_StopOnThrow 1
|
||||
#define STOP CADebuggerStop()
|
||||
#else
|
||||
#define STOP
|
||||
#endif
|
||||
|
||||
#if CoreAudio_StopOnAssert
|
||||
#if !CoreAudio_StopOnFailure
|
||||
#include "CADebugger.h"
|
||||
#define STOP
|
||||
#endif
|
||||
#define __ASSERT_STOP CADebuggerStop()
|
||||
#else
|
||||
#define __ASSERT_STOP
|
||||
#endif
|
||||
|
||||
#if CoreAudio_StopOnThrow
|
||||
#if !CoreAudio_StopOnFailure
|
||||
#include "CADebugger.h"
|
||||
#define STOP
|
||||
#endif
|
||||
#define __THROW_STOP CADebuggerStop()
|
||||
#else
|
||||
#define __THROW_STOP
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define DebugMsg(inFormat, ...)
|
||||
#ifndef DEBUGPRINT
|
||||
#define DEBUGPRINT(msg)
|
||||
#endif
|
||||
#define vprint(msg)
|
||||
#define STOP
|
||||
#define __ASSERT_STOP
|
||||
#define __THROW_STOP
|
||||
#endif
|
||||
|
||||
// Old-style numbered DebugMessage calls are implemented in terms of DebugMsg() now
|
||||
#define DebugMessage(msg) DebugMsg(msg)
|
||||
#define DebugMessageN1(msg, N1) DebugMsg(msg, N1)
|
||||
#define DebugMessageN2(msg, N1, N2) DebugMsg(msg, N1, N2)
|
||||
#define DebugMessageN3(msg, N1, N2, N3) DebugMsg(msg, N1, N2, N3)
|
||||
#define DebugMessageN4(msg, N1, N2, N3, N4) DebugMsg(msg, N1, N2, N3, N4)
|
||||
#define DebugMessageN5(msg, N1, N2, N3, N4, N5) DebugMsg(msg, N1, N2, N3, N4, N5)
|
||||
#define DebugMessageN6(msg, N1, N2, N3, N4, N5, N6) DebugMsg(msg, N1, N2, N3, N4, N5, N6)
|
||||
#define DebugMessageN7(msg, N1, N2, N3, N4, N5, N6, N7) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7)
|
||||
#define DebugMessageN8(msg, N1, N2, N3, N4, N5, N6, N7, N8) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8)
|
||||
#define DebugMessageN9(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9) DebugMsg(msg, N1, N2, N3, N4, N5, N6, N7, N8, N9)
|
||||
|
||||
// VC edit: Added __printflike.
|
||||
void LogError(const char *fmt, ...) __printflike(1, 2); // writes to syslog (and stderr if debugging)
|
||||
void LogWarning(const char *fmt, ...) __printflike(1, 2); // writes to syslog (and stderr if debugging)
|
||||
|
||||
#define NO_ACTION (void)0
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
|
||||
#pragma mark Debug Macros
|
||||
|
||||
#define Assert(inCondition, inMessage) \
|
||||
if(!(inCondition)) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
__ASSERT_STOP; \
|
||||
}
|
||||
|
||||
#define AssertFileLine(inCondition, inMessage) \
|
||||
if(!(inCondition)) \
|
||||
{ \
|
||||
DebugMessageN3("%s, line %d: %s", __FILE__, __LINE__, inMessage); \
|
||||
__ASSERT_STOP; \
|
||||
}
|
||||
|
||||
#define AssertNoError(inError, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
char __4CC[5] = CA4CCToCString(__Err); \
|
||||
DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define AssertNoKernelError(inError, inMessage) \
|
||||
{ \
|
||||
unsigned int __Err = (unsigned int)(inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define AssertNotNULL(inPtr, inMessage) \
|
||||
{ \
|
||||
if((inPtr) == NULL) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIf(inCondition, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
STOP; \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \
|
||||
{ \
|
||||
unsigned int __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIfError(inError, inAction, inHandler, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
char __4CC[5] = CA4CCToCString(__Err); \
|
||||
DebugMessageN2(inMessage ", Error: %ld (%s)", (long int)__Err, __4CC); \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIfNoMessage(inCondition, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \
|
||||
{ \
|
||||
unsigned int __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#define Throw(inException) __THROW_STOP; throw (inException)
|
||||
|
||||
#define ThrowIf(inCondition, inException, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#define ThrowIfNULL(inPointer, inException, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
DebugMessage(inMessage); \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#define ThrowIfKernelError(inKernelError, inException, inMessage) \
|
||||
{ \
|
||||
int __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
DebugMessageN1(inMessage ", Error: 0x%X", __Err); \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ThrowIfError(inError, inException, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
char __4CC[5] = CA4CCToCString(__Err); \
|
||||
DebugMessageN2(inMessage ", Error: %d (%s)", (int)__Err, __4CC); \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#define ThrowIfWinError(inError, inException, inMessage) \
|
||||
{ \
|
||||
HRESULT __Err = (inError); \
|
||||
if(FAILED(__Err)) \
|
||||
{ \
|
||||
DebugMessageN2(inMessage ", Code: %d, Facility: 0x%X", HRESULT_CODE(__Err), HRESULT_FACILITY(__Err)); \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SubclassResponsibility(inMethodName, inException) \
|
||||
{ \
|
||||
DebugMessage(inMethodName": Subclasses must implement this method"); \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#endif // defined(__cplusplus)
|
||||
|
||||
#else
|
||||
|
||||
#pragma mark Release Macros
|
||||
|
||||
#define Assert(inCondition, inMessage) \
|
||||
if(!(inCondition)) \
|
||||
{ \
|
||||
__ASSERT_STOP; \
|
||||
}
|
||||
|
||||
#define AssertFileLine(inCondition, inMessage) Assert(inCondition, inMessage)
|
||||
|
||||
#define AssertNoError(inError, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define AssertNoKernelError(inError, inMessage) \
|
||||
{ \
|
||||
unsigned int __Err = (unsigned int)(inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define AssertNotNULL(inPtr, inMessage) \
|
||||
{ \
|
||||
if((inPtr) == NULL) \
|
||||
{ \
|
||||
__ASSERT_STOP; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIf(inCondition, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailWithAction(inCondition, inAction, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfNULL(inPointer, inAction, inHandler, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfKernelError(inKernelError, inAction, inHandler, inMessage) \
|
||||
if((inKernelError) != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfError(inError, inAction, inHandler, inMessage) \
|
||||
if((inError) != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfNoMessage(inCondition, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailWithActionNoMessage(inCondition, inAction, inHandler, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfNULLNoMessage(inPointer, inAction, inHandler, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
}
|
||||
|
||||
#define FailIfKernelErrorNoMessage(inKernelError, inAction, inHandler, inMessage) \
|
||||
{ \
|
||||
unsigned int __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define FailIfErrorNoMessage(inError, inAction, inHandler, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
STOP; \
|
||||
{ inAction; } \
|
||||
goto inHandler; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(__cplusplus)
|
||||
|
||||
#define Throw(inException) __THROW_STOP; throw (inException)
|
||||
|
||||
#define ThrowIf(inCondition, inException, inMessage) \
|
||||
if(inCondition) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#define ThrowIfNULL(inPointer, inException, inMessage) \
|
||||
if((inPointer) == NULL) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
// VC edit: Changed "unsigned int" to "int" to silence -Wsign-conversion.
|
||||
#define ThrowIfKernelError(inKernelError, inException, inMessage) \
|
||||
{ \
|
||||
int __Err = (inKernelError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ThrowIfError(inError, inException, inMessage) \
|
||||
{ \
|
||||
SInt32 __Err = (inError); \
|
||||
if(__Err != 0) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#define ThrowIfWinError(inError, inException, inMessage) \
|
||||
{ \
|
||||
HRESULT __Err = (inError); \
|
||||
if(FAILED(__Err)) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SubclassResponsibility(inMethodName, inException) \
|
||||
{ \
|
||||
Throw(inException); \
|
||||
}
|
||||
|
||||
#endif // defined(__cplusplus)
|
||||
|
||||
#endif // DEBUG || CoreAudio_Debug
|
||||
|
||||
#endif
|
||||
89
driver/PublicUtility/CADebugPrintf.cpp
Normal file
89
driver/PublicUtility/CADebugPrintf.cpp
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
File: CADebugPrintf.cpp
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CADebugPrintf.h"
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <Windows.h>
|
||||
extern "C"
|
||||
int CAWin32DebugPrintf(char* inFormat, ...)
|
||||
{
|
||||
char theMessage[1024];
|
||||
va_list theArguments;
|
||||
va_start(theArguments, inFormat);
|
||||
_vsnprintf(theMessage, 1024, inFormat, theArguments);
|
||||
va_end(theArguments);
|
||||
OutputDebugString(theMessage);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CoreAudio_UseSideFile)
|
||||
#include <unistd.h>
|
||||
FILE* sDebugPrintfSideFile = NULL;
|
||||
extern "C"
|
||||
void OpenDebugPrintfSideFile()
|
||||
{
|
||||
if(sDebugPrintfSideFile == NULL)
|
||||
{
|
||||
char theFileName[1024];
|
||||
snprintf(theFileName, sizeof(theFileName), CoreAudio_UseSideFile, getpid());
|
||||
sDebugPrintfSideFile = fopen(theFileName, "a+");
|
||||
DebugPrintfRtn(DebugPrintfFileComma "\n------------------------------\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
115
driver/PublicUtility/CADebugPrintf.h
Normal file
115
driver/PublicUtility/CADebugPrintf.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
File: CADebugPrintf.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CADebugPrintf_h__)
|
||||
#define __CADebugPrintf_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// Macros to redirect debugging output to various logging services
|
||||
//=============================================================================
|
||||
|
||||
//#define CoreAudio_UseSysLog 1
|
||||
//#define CoreAudio_UseSideFile "/CoreAudio-%d.txt"
|
||||
|
||||
#if DEBUG || CoreAudio_Debug
|
||||
|
||||
#if TARGET_OS_WIN32
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
extern int CAWin32DebugPrintf(char* inFormat, ...);
|
||||
#define DebugPrintfRtn CAWin32DebugPrintf
|
||||
#define DebugPrintfFile
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma
|
||||
#else
|
||||
#if CoreAudio_UseSysLog
|
||||
#include <sys/syslog.h>
|
||||
#define DebugPrintfRtn syslog
|
||||
#define DebugPrintfFile LOG_NOTICE
|
||||
#define DebugPrintfLineEnding ""
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#elif defined(CoreAudio_UseSideFile)
|
||||
#include <stdio.h>
|
||||
#if defined(__cplusplus)
|
||||
extern "C"
|
||||
#endif
|
||||
void OpenDebugPrintfSideFile();
|
||||
extern FILE* sDebugPrintfSideFile;
|
||||
#define DebugPrintfRtn fprintf
|
||||
#define DebugPrintfFile ((sDebugPrintfSideFile != NULL) ? sDebugPrintfSideFile : stderr)
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#define DebugPrintfRtn fprintf
|
||||
#define DebugPrintfFile stderr
|
||||
#define DebugPrintfLineEnding "\n"
|
||||
#define DebugPrintfFileComma DebugPrintfFile,
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DebugPrintf(inFormat, ...) DebugPrintfRtn(DebugPrintfFileComma inFormat DebugPrintfLineEnding, ## __VA_ARGS__)
|
||||
#else
|
||||
#define DebugPrintfRtn
|
||||
#define DebugPrintfFile
|
||||
#define DebugPrintfLineEnding
|
||||
#define DebugPrintfFileComma
|
||||
#define DebugPrintf(inFormat, ...)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
103
driver/PublicUtility/CADebugger.cpp
Normal file
103
driver/PublicUtility/CADebugger.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
File: CADebugger.cpp
|
||||
Abstract: CADebugger.h
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CADebugger.h"
|
||||
|
||||
//=============================================================================
|
||||
// CADebugger
|
||||
//=============================================================================
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
|
||||
#include <sys/sysctl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
bool CAIsDebuggerAttached(void)
|
||||
{
|
||||
int mib[4];
|
||||
struct kinfo_proc info;
|
||||
size_t size;
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = getpid();
|
||||
size = sizeof(info);
|
||||
info.kp_proc.p_flag = 0;
|
||||
|
||||
sysctl(mib, 4, &info, &size, NULL, 0);
|
||||
|
||||
return (info.kp_proc.p_flag & P_TRACED) == P_TRACED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void CADebuggerStop(void)
|
||||
{
|
||||
#if CoreAudio_Debug
|
||||
#if TARGET_API_MAC_OSX
|
||||
if(CAIsDebuggerAttached())
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
asm("int3");
|
||||
#else
|
||||
__builtin_trap();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
abort();
|
||||
}
|
||||
#else
|
||||
__debugbreak();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
69
driver/PublicUtility/CADebugger.h
Normal file
69
driver/PublicUtility/CADebugger.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
File: CADebugger.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CADebugger_h__)
|
||||
#define __CADebugger_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CADebugger
|
||||
//=============================================================================
|
||||
|
||||
#if TARGET_API_MAC_OSX
|
||||
extern bool CAIsDebuggerAttached(void);
|
||||
#endif
|
||||
extern void CADebuggerStop(void);
|
||||
|
||||
#endif
|
||||
438
driver/PublicUtility/CADispatchQueue.cpp
Normal file
438
driver/PublicUtility/CADispatchQueue.cpp
Normal file
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
File: CADispatchQueue.cpp
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
/*==================================================================================================
|
||||
CADispatchQueue.cpp
|
||||
==================================================================================================*/
|
||||
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CADispatchQueue.h"
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CACFString.h"
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAException.h"
|
||||
#include "CAHostTimeBase.h"
|
||||
|
||||
// System Includes
|
||||
#include <mach/mach.h>
|
||||
|
||||
// Standard Library Includes
|
||||
#include <algorithm>
|
||||
|
||||
//==================================================================================================
|
||||
// CADispatchQueue
|
||||
//==================================================================================================
|
||||
|
||||
CADispatchQueue::CADispatchQueue(const char* inName)
|
||||
:
|
||||
mDispatchQueue(NULL),
|
||||
mPortDeathList(),
|
||||
mMachPortReceiverList()
|
||||
{
|
||||
mDispatchQueue = dispatch_queue_create(inName, NULL);
|
||||
ThrowIfNULL(mDispatchQueue, CAException('what'), "CADispatchQueue::CADispatchQueue: failed to create the dispatch queue");
|
||||
}
|
||||
|
||||
CADispatchQueue::CADispatchQueue(CFStringRef inName)
|
||||
:
|
||||
mDispatchQueue(NULL),
|
||||
mPortDeathList(),
|
||||
mMachPortReceiverList()
|
||||
{
|
||||
CACFString theCFName(inName, false);
|
||||
char theName[256];
|
||||
UInt32 theSize = 256;
|
||||
theCFName.GetCString(theName, theSize);
|
||||
mDispatchQueue = dispatch_queue_create(theName, NULL);
|
||||
ThrowIfNULL(mDispatchQueue, CAException('what'), "CADispatchQueue::CADispatchQueue: failed to create the dispatch queue");
|
||||
}
|
||||
|
||||
CADispatchQueue::CADispatchQueue(CFStringRef inPattern, CFStringRef inName)
|
||||
:
|
||||
mDispatchQueue(NULL),
|
||||
mPortDeathList(),
|
||||
mMachPortReceiverList()
|
||||
{
|
||||
CACFString theCFName(CFStringCreateWithFormat(NULL, NULL, inPattern, inName), true);
|
||||
char theName[256];
|
||||
UInt32 theSize = 256;
|
||||
theCFName.GetCString(theName, theSize);
|
||||
mDispatchQueue = dispatch_queue_create(theName, NULL);
|
||||
ThrowIfNULL(mDispatchQueue, CAException('what'), "CADispatchQueue::CADispatchQueue: failed to create the dispatch queue");
|
||||
}
|
||||
|
||||
CADispatchQueue::~CADispatchQueue()
|
||||
{
|
||||
// Clean up the port death watchers if any are still around. Note that we do this explicitly to
|
||||
// be sure the source is cleaned up before the queue is released
|
||||
mPortDeathList.clear();
|
||||
Assert(mMachPortReceiverList.size() == 0, "CADispatchQueue::~CADispatchQueue: Implicitly removing the mach port receviers. It is best to explicitly call RemoveMachPortRecevier().");
|
||||
mMachPortReceiverList.clear();
|
||||
|
||||
// release the dispatch queue
|
||||
dispatch_release(mDispatchQueue);
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch(bool inDoSync, dispatch_block_t inTask) const
|
||||
{
|
||||
if(inDoSync)
|
||||
{
|
||||
// Executing a task synchronously while already on the dispatch queue will result in a deadlock
|
||||
dispatch_sync(mDispatchQueue, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async(mDispatchQueue, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch(UInt64 inNanoseconds, dispatch_block_t inTask) const
|
||||
{
|
||||
if(inNanoseconds == 0)
|
||||
{
|
||||
dispatch_async(mDispatchQueue, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_after(dispatch_time(0, static_cast<int64_t>(CAHostTimeBase::ConvertFromNanos(inNanoseconds))), mDispatchQueue, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch(bool inDoSync, void* inTaskContext, dispatch_function_t inTask) const
|
||||
{
|
||||
if(inDoSync)
|
||||
{
|
||||
// Executing a task synchronously while already on the dispatch queue will result in a deadlock
|
||||
dispatch_sync_f(mDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async_f(mDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch(UInt64 inNanoseconds, void* inTaskContext, dispatch_function_t inTask) const
|
||||
{
|
||||
if(inNanoseconds == 0)
|
||||
{
|
||||
dispatch_async_f(mDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_after_f(dispatch_time(0, static_cast<int64_t>(CAHostTimeBase::ConvertFromNanos(inNanoseconds))), mDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Global(dispatch_queue_priority_t inQueuePriority, bool inDoSync, dispatch_block_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_global_queue(inQueuePriority, 0);
|
||||
if(inDoSync)
|
||||
{
|
||||
// Executing a task synchronously while already on the dispatch queue will result in a deadlock
|
||||
dispatch_sync(theDispatchQueue, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async(theDispatchQueue, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Global(dispatch_queue_priority_t inQueuePriority, UInt64 inNanoseconds, dispatch_block_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_global_queue(inQueuePriority, 0);
|
||||
if(inNanoseconds == 0)
|
||||
{
|
||||
dispatch_async(theDispatchQueue, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_after(dispatch_time(0, static_cast<int64_t>(CAHostTimeBase::ConvertFromNanos(inNanoseconds))), theDispatchQueue, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Global(dispatch_queue_priority_t inQueuePriority, bool inDoSync, void* inTaskContext, dispatch_function_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_global_queue(inQueuePriority, 0);
|
||||
if(inDoSync)
|
||||
{
|
||||
// Executing a task synchronously while already on the dispatch queue will result in a deadlock
|
||||
dispatch_sync_f(theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async_f(theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Global(dispatch_queue_priority_t inQueuePriority, UInt64 inNanoseconds, void* inTaskContext, dispatch_function_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_global_queue(inQueuePriority, 0);
|
||||
if(inNanoseconds == 0)
|
||||
{
|
||||
dispatch_async_f(theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_after_f(dispatch_time(0, static_cast<int64_t>(CAHostTimeBase::ConvertFromNanos(inNanoseconds))), theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Main(bool inDoSync, dispatch_block_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_main_queue();
|
||||
if(inDoSync)
|
||||
{
|
||||
// Executing a task synchronously while already on the dispatch queue will result in a deadlock
|
||||
dispatch_sync(theDispatchQueue, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async(theDispatchQueue, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Main(UInt64 inNanoseconds, dispatch_block_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_main_queue();
|
||||
if(inNanoseconds == 0)
|
||||
{
|
||||
dispatch_async(theDispatchQueue, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_after(dispatch_time(0, static_cast<int64_t>(CAHostTimeBase::ConvertFromNanos(inNanoseconds))), theDispatchQueue, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Main(bool inDoSync, void* inTaskContext, dispatch_function_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_main_queue();
|
||||
if(inDoSync)
|
||||
{
|
||||
// Executing a task synchronously while already on the dispatch queue will result in a deadlock
|
||||
dispatch_sync_f(theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_async_f(theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::Dispatch_Main(UInt64 inNanoseconds, void* inTaskContext, dispatch_function_t inTask)
|
||||
{
|
||||
dispatch_queue_t theDispatchQueue = dispatch_get_main_queue();
|
||||
if(inNanoseconds == 0)
|
||||
{
|
||||
dispatch_async_f(theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
else
|
||||
{
|
||||
dispatch_after_f(dispatch_time(0, static_cast<int64_t>(CAHostTimeBase::ConvertFromNanos(inNanoseconds))), theDispatchQueue, inTaskContext, inTask);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::InstallMachPortDeathNotification(mach_port_t inMachPort, dispatch_block_t inNotificationTask)
|
||||
{
|
||||
ThrowIf(inMachPort == MACH_PORT_NULL, CAException('nope'), "CADispatchQueue::InstallMachPortDeathNotification: a mach port is required");
|
||||
|
||||
// look in the list to see if we've already created an event source for it
|
||||
bool wasFound = false;
|
||||
EventSourceList::iterator theIterator = mPortDeathList.begin();
|
||||
while(!wasFound && (theIterator != mPortDeathList.end()))
|
||||
{
|
||||
wasFound = theIterator->mMachPort == inMachPort;
|
||||
if(!wasFound)
|
||||
{
|
||||
++theIterator;
|
||||
}
|
||||
}
|
||||
|
||||
// create and install the event source for the port
|
||||
if(!wasFound)
|
||||
{
|
||||
// create an event source for the mach port
|
||||
dispatch_source_t theDispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, inMachPort, DISPATCH_MACH_SEND_DEAD, mDispatchQueue);
|
||||
ThrowIfNULL(theDispatchSource, CAException('what'), "CADispatchQueue::InstallMachPortDeathNotification: failed to create the mach port event source");
|
||||
|
||||
// install the event handler
|
||||
dispatch_source_set_event_handler(theDispatchSource, inNotificationTask);
|
||||
|
||||
// put the info in the list
|
||||
mPortDeathList.push_back(EventSource(theDispatchSource, inMachPort));
|
||||
|
||||
// resume the event source so that it can start handling messages and also so that the source can be released
|
||||
dispatch_resume(theDispatchSource);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::RemoveMachPortDeathNotification(mach_port_t inMachPort)
|
||||
{
|
||||
bool wasFound = false;
|
||||
EventSourceList::iterator theIterator = mPortDeathList.begin();
|
||||
while(!wasFound && (theIterator != mPortDeathList.end()))
|
||||
{
|
||||
wasFound = theIterator->mMachPort == inMachPort;
|
||||
if(!wasFound)
|
||||
{
|
||||
++theIterator;
|
||||
}
|
||||
}
|
||||
if(wasFound)
|
||||
{
|
||||
if(theIterator->mDispatchSource != NULL)
|
||||
{
|
||||
dispatch_source_cancel(theIterator->mDispatchSource);
|
||||
}
|
||||
mPortDeathList.erase(theIterator);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::InstallMachPortReceiver(mach_port_t inMachPort, dispatch_block_t inMessageTask)
|
||||
{
|
||||
ThrowIf(inMachPort == MACH_PORT_NULL, CAException('nope'), "CADispatchQueue::InstallMachPortReceiver: a mach port is required");
|
||||
|
||||
// look in the list to see if we've already created an event source for it
|
||||
bool wasFound = false;
|
||||
EventSourceList::iterator theIterator = mMachPortReceiverList.begin();
|
||||
while(!wasFound && (theIterator != mMachPortReceiverList.end()))
|
||||
{
|
||||
wasFound = theIterator->mMachPort == inMachPort;
|
||||
if(!wasFound)
|
||||
{
|
||||
++theIterator;
|
||||
}
|
||||
}
|
||||
|
||||
// create and install the event source for the port
|
||||
if(!wasFound)
|
||||
{
|
||||
// create an event source for the mach port
|
||||
dispatch_source_t theDispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, inMachPort, 0, mDispatchQueue);
|
||||
ThrowIfNULL(theDispatchSource, CAException('what'), "CADispatchQueue::InstallMachPortReceiver: failed to create the mach port event source");
|
||||
|
||||
// install an event handler that maps the mach messages to the MIG server function
|
||||
dispatch_source_set_event_handler(theDispatchSource, inMessageTask);
|
||||
|
||||
// put the info in the list
|
||||
mMachPortReceiverList.push_back(EventSource(theDispatchSource, inMachPort));
|
||||
|
||||
// resume the event source so that it can start handling messages and also so that the source can be released
|
||||
dispatch_resume(theDispatchSource);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::RemoveMachPortReceiver(mach_port_t inMachPort, dispatch_block_t inCompletionTask)
|
||||
{
|
||||
bool wasFound = false;
|
||||
EventSourceList::iterator theIterator = mMachPortReceiverList.begin();
|
||||
while(!wasFound && (theIterator != mMachPortReceiverList.end()))
|
||||
{
|
||||
wasFound = theIterator->mMachPort == inMachPort;
|
||||
if(!wasFound)
|
||||
{
|
||||
++theIterator;
|
||||
}
|
||||
}
|
||||
if(wasFound)
|
||||
{
|
||||
if(theIterator->mDispatchSource != NULL)
|
||||
{
|
||||
// Set the cancel handler to the completion block. Note that the mach port cannot be freed
|
||||
// before the completion block runs due to a race condition. See the note in the comments
|
||||
// dispatch_source_set_cancel_handler in <dispatch/source.h>.
|
||||
if(inCompletionTask != 0)
|
||||
{
|
||||
dispatch_source_set_cancel_handler(theIterator->mDispatchSource, inCompletionTask);
|
||||
}
|
||||
|
||||
dispatch_source_cancel(theIterator->mDispatchSource);
|
||||
}
|
||||
mMachPortReceiverList.erase(theIterator);
|
||||
}
|
||||
}
|
||||
|
||||
void CADispatchQueue::RemoveMachPortReceiver(mach_port_t inMachPort, bool inDestroySendRight, bool inDestroyReceiveRight)
|
||||
{
|
||||
RemoveMachPortReceiver(inMachPort, ^{
|
||||
if(inDestroySendRight)
|
||||
{
|
||||
kern_return_t theError = mach_port_deallocate(mach_task_self(), inMachPort);
|
||||
AssertNoKernelError(theError, "CADispatchQueue::RemoveMachPortReceiver: deallocating the send right failed");
|
||||
}
|
||||
if(inDestroyReceiveRight)
|
||||
{
|
||||
kern_return_t theError = mach_port_mod_refs(mach_task_self(), inMachPort, MACH_PORT_RIGHT_RECEIVE, -1);
|
||||
AssertNoKernelError(theError, "CADispatchQueue::RemoveMachPortReceiver: deallocating the receive right failed");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CADispatchQueue& CADispatchQueue::GetGlobalSerialQueue()
|
||||
{
|
||||
dispatch_once_f(&sGlobalSerialQueueInitialized, NULL, InitializeGlobalSerialQueue);
|
||||
ThrowIfNULL(sGlobalSerialQueue, CAException('nope'), "CADispatchQueue::GetGlobalSerialQueue: there is no global serial queue");
|
||||
return *sGlobalSerialQueue;
|
||||
}
|
||||
|
||||
void CADispatchQueue::InitializeGlobalSerialQueue(void*)
|
||||
{
|
||||
try
|
||||
{
|
||||
sGlobalSerialQueue = new CADispatchQueue("com.apple.audio.CADispatchQueue.SerialQueue");
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
sGlobalSerialQueue = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CADispatchQueue* CADispatchQueue::sGlobalSerialQueue = NULL;
|
||||
dispatch_once_t CADispatchQueue::sGlobalSerialQueueInitialized = 0;
|
||||
235
driver/PublicUtility/CADispatchQueue.h
Normal file
235
driver/PublicUtility/CADispatchQueue.h
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
File: CADispatchQueue.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
/*==================================================================================================
|
||||
CADispatchQueue.h
|
||||
==================================================================================================*/
|
||||
#if !defined(__CADispatchQueue_h__)
|
||||
#define __CADispatchQueue_h__
|
||||
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// System Includes
|
||||
#include <CoreFoundation/CFString.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
// Standard Library Includes
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
/*==================================================================================================
|
||||
CADispatchQueue
|
||||
|
||||
This class provides a wrapper for a libdispatch dispatch queue and several kinds of event
|
||||
sources such as MIG servers, port death notifications and other mach port related support. Being
|
||||
a libdispatch client, the unit of work is represented as either a function pointer and context
|
||||
pointer pair or as a Block.
|
||||
|
||||
One thing to keep in mind when using a Block-based construct is that you get a copy of the
|
||||
pointer but you do not get a copy of the memory that the pointer is pointing at. The net effect
|
||||
is that if you have a task that frees the memory that is referenced by a subsequent task,
|
||||
this second task would crash when dereferencing the pointer. This means that every task
|
||||
needs to include some code to validate any pointers it is using before dereferencing them.
|
||||
|
||||
A common example of this problem comes up with C++ objects. Suppose you have an instance method
|
||||
that creates a Block that calls other instance methods or accesses the object's fields. Suppose
|
||||
further that the Block is submitted to a dispatch queue for execution. If the object gets
|
||||
deallocated before the Block can run, the Block will crash. Thus, the Block needs to validate
|
||||
that the "this" pointer is still valid when it executes.
|
||||
|
||||
Another place where this comes up often is when attempting to implment a function by dispatching
|
||||
the work asynchronously. Any arguments to the function that point to the stack will be invalid.
|
||||
This is particularly troublesome inside of a MIG function.
|
||||
|
||||
Still another common issue with using Blocks and dispatch functions with C++ is that it is vital
|
||||
that no exceptions ever leave a Block or a dispatch function. If an exception was thrown out of
|
||||
a block, the result would be undefined and probably would result in the program calling
|
||||
the terminate() function in the standard C++ library (whose default implementation is to call
|
||||
abort(3)). Given that, all Blocks and dispatch functions that might end up throwing an exception
|
||||
need to catch those exceptions.
|
||||
==================================================================================================*/
|
||||
|
||||
class CADispatchQueue
|
||||
{
|
||||
|
||||
#pragma mark Construction/Destruction
|
||||
public:
|
||||
CADispatchQueue(const char* inName);
|
||||
CADispatchQueue(CFStringRef inName);
|
||||
CADispatchQueue(CFStringRef inPattern, CFStringRef inName);
|
||||
virtual ~CADispatchQueue();
|
||||
|
||||
private:
|
||||
CADispatchQueue(const CADispatchQueue&);
|
||||
CADispatchQueue& operator=(const CADispatchQueue&);
|
||||
|
||||
#pragma mark Execution Operations
|
||||
public:
|
||||
void Dispatch(bool inDoSync, dispatch_block_t inTask) const;
|
||||
void Dispatch(UInt64 inNanoseconds, dispatch_block_t inTask) const;
|
||||
|
||||
void Dispatch(bool inDoSync, void* inTaskContext, dispatch_function_t inTask) const;
|
||||
void Dispatch(UInt64 inNanoseconds, void* inTaskContext, dispatch_function_t inTask) const;
|
||||
|
||||
static void Dispatch_Global(dispatch_queue_priority_t inQueuePriority, bool inDoSync, dispatch_block_t inTask);
|
||||
static void Dispatch_Global(dispatch_queue_priority_t inQueuePriority, UInt64 inNanoseconds, dispatch_block_t inTask);
|
||||
|
||||
static void Dispatch_Global(dispatch_queue_priority_t inQueuePriority, bool inDoSync, void* inTaskContext, dispatch_function_t inTask);
|
||||
static void Dispatch_Global(dispatch_queue_priority_t inQueuePriority, UInt64 inNanoseconds, void* inTaskContext, dispatch_function_t inTask);
|
||||
|
||||
static void Dispatch_Main(bool inDoSync, dispatch_block_t inTask);
|
||||
static void Dispatch_Main(UInt64 inNanoseconds, dispatch_block_t inTask);
|
||||
|
||||
static void Dispatch_Main(bool inDoSync, void* inTaskContext, dispatch_function_t inTask);
|
||||
static void Dispatch_Main(UInt64 inNanoseconds, void* inTaskContext, dispatch_function_t inTask);
|
||||
|
||||
#pragma mark Event Sources
|
||||
public:
|
||||
void InstallMachPortDeathNotification(mach_port_t inMachPort, dispatch_block_t inNotificationTask);
|
||||
void RemoveMachPortDeathNotification(mach_port_t inMachPort);
|
||||
|
||||
void InstallMachPortReceiver(mach_port_t inMachPort, dispatch_block_t inMessageTask);
|
||||
void RemoveMachPortReceiver(mach_port_t inMachPort, dispatch_block_t inCompletionTask);
|
||||
void RemoveMachPortReceiver(mach_port_t inMachPort, bool inDestroySendRight, bool inDestroyReceiveRight);
|
||||
|
||||
#pragma mark Implementation
|
||||
public:
|
||||
dispatch_queue_t GetDispatchQueue() const;
|
||||
|
||||
static CADispatchQueue& GetGlobalSerialQueue();
|
||||
|
||||
protected:
|
||||
static void InitializeGlobalSerialQueue(void*);
|
||||
|
||||
struct EventSource
|
||||
{
|
||||
dispatch_source_t mDispatchSource;
|
||||
mach_port_t mMachPort;
|
||||
|
||||
EventSource();
|
||||
EventSource(dispatch_source_t inDispatchSource, mach_port_t inMachPort);
|
||||
EventSource(const EventSource& inEventSource);
|
||||
EventSource& operator=(const EventSource& inEventSource);
|
||||
~EventSource();
|
||||
void Retain();
|
||||
void Release();
|
||||
};
|
||||
typedef std::vector<EventSource> EventSourceList;
|
||||
|
||||
dispatch_queue_t mDispatchQueue;
|
||||
EventSourceList mPortDeathList;
|
||||
EventSourceList mMachPortReceiverList;
|
||||
|
||||
static CADispatchQueue* sGlobalSerialQueue;
|
||||
static dispatch_once_t sGlobalSerialQueueInitialized;
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
#pragma mark CADispatchQueue Inline Method Implementations
|
||||
//==================================================================================================
|
||||
|
||||
inline dispatch_queue_t CADispatchQueue::GetDispatchQueue() const
|
||||
{
|
||||
return mDispatchQueue;
|
||||
}
|
||||
|
||||
inline CADispatchQueue::EventSource::EventSource()
|
||||
:
|
||||
mDispatchSource(NULL),
|
||||
mMachPort(MACH_PORT_NULL)
|
||||
{
|
||||
}
|
||||
|
||||
inline CADispatchQueue::EventSource::EventSource(dispatch_source_t inDispatchSource, mach_port_t inMachPort)
|
||||
:
|
||||
mDispatchSource(inDispatchSource),
|
||||
mMachPort(inMachPort)
|
||||
{
|
||||
}
|
||||
|
||||
inline CADispatchQueue::EventSource::EventSource(const EventSource& inEventSource)
|
||||
:
|
||||
mDispatchSource(inEventSource.mDispatchSource),
|
||||
mMachPort(inEventSource.mMachPort)
|
||||
{
|
||||
Retain();
|
||||
}
|
||||
|
||||
inline CADispatchQueue::EventSource& CADispatchQueue::EventSource::operator=(const EventSource& inEventSource)
|
||||
{
|
||||
Release();
|
||||
mDispatchSource = inEventSource.mDispatchSource;
|
||||
mMachPort = inEventSource.mMachPort;
|
||||
Retain();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline CADispatchQueue::EventSource::~EventSource()
|
||||
{
|
||||
Release();
|
||||
}
|
||||
|
||||
inline void CADispatchQueue::EventSource::Retain()
|
||||
{
|
||||
if(mDispatchSource != NULL)
|
||||
{
|
||||
dispatch_retain(mDispatchSource);
|
||||
}
|
||||
}
|
||||
|
||||
inline void CADispatchQueue::EventSource::Release()
|
||||
{
|
||||
if(mDispatchSource != NULL)
|
||||
{
|
||||
dispatch_release(mDispatchSource);
|
||||
mDispatchSource = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __CADispatchQueue_h__
|
||||
83
driver/PublicUtility/CAException.h
Normal file
83
driver/PublicUtility/CAException.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
File: CAException.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAException_h__)
|
||||
#define __CAException_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include "CoreAudioTypes.h"
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAException
|
||||
//=============================================================================
|
||||
|
||||
class CAException
|
||||
{
|
||||
|
||||
public:
|
||||
CAException(OSStatus inError) : mError(inError) {}
|
||||
CAException(const CAException& inException) : mError(inException.mError) {}
|
||||
CAException& operator=(const CAException& inException) { mError = inException.mError; return *this; }
|
||||
~CAException() {}
|
||||
|
||||
OSStatus GetError() const { return mError; }
|
||||
|
||||
protected:
|
||||
OSStatus mError;
|
||||
};
|
||||
|
||||
#define CATry try{
|
||||
#define CACatch } catch(...) {}
|
||||
#define CASwallowException(inExpression) try { inExpression; } catch(...) {}
|
||||
|
||||
#endif
|
||||
99
driver/PublicUtility/CAHostTimeBase.cpp
Normal file
99
driver/PublicUtility/CAHostTimeBase.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
File: CAHostTimeBase.cpp
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CAHostTimeBase.h"
|
||||
|
||||
Float64 CAHostTimeBase::sFrequency = 0;
|
||||
Float64 CAHostTimeBase::sInverseFrequency = 0;
|
||||
UInt32 CAHostTimeBase::sMinDelta = 0;
|
||||
UInt32 CAHostTimeBase::sToNanosNumerator = 0;
|
||||
UInt32 CAHostTimeBase::sToNanosDenominator = 0;
|
||||
pthread_once_t CAHostTimeBase::sIsInited = PTHREAD_ONCE_INIT;
|
||||
#if Track_Host_TimeBase
|
||||
UInt64 CAHostTimeBase::sLastTime = 0;
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// CAHostTimeBase
|
||||
//
|
||||
// This class provides platform independent access to the host's time base.
|
||||
//=============================================================================
|
||||
|
||||
void CAHostTimeBase::Initialize()
|
||||
{
|
||||
// get the info about Absolute time
|
||||
#if TARGET_OS_MAC
|
||||
struct mach_timebase_info theTimeBaseInfo;
|
||||
mach_timebase_info(&theTimeBaseInfo);
|
||||
sMinDelta = 1;
|
||||
sToNanosNumerator = theTimeBaseInfo.numer;
|
||||
sToNanosDenominator = theTimeBaseInfo.denom;
|
||||
|
||||
// the frequency of that clock is: (sToNanosDenominator / sToNanosNumerator) * 10^9
|
||||
sFrequency = static_cast<Float64>(sToNanosDenominator) / static_cast<Float64>(sToNanosNumerator);
|
||||
sFrequency *= 1000000000.0;
|
||||
#elif TARGET_OS_WIN32
|
||||
LARGE_INTEGER theFrequency;
|
||||
QueryPerformanceFrequency(&theFrequency);
|
||||
sMinDelta = 1;
|
||||
sToNanosNumerator = 1000000000ULL;
|
||||
sToNanosDenominator = *((UInt64*)&theFrequency);
|
||||
sFrequency = static_cast<Float64>(*((UInt64*)&theFrequency));
|
||||
#endif
|
||||
sInverseFrequency = 1.0 / sFrequency;
|
||||
|
||||
#if Log_Host_Time_Base_Parameters
|
||||
DebugPrintf("Host Time Base Parameters");
|
||||
DebugPrintf(" Minimum Delta: %lu", (unsigned long)sMinDelta);
|
||||
DebugPrintf(" Frequency: %f", sFrequency);
|
||||
DebugPrintf(" To Nanos Numerator: %lu", (unsigned long)sToNanosNumerator);
|
||||
DebugPrintf(" To Nanos Denominator: %lu", (unsigned long)sToNanosDenominator);
|
||||
#endif
|
||||
}
|
||||
234
driver/PublicUtility/CAHostTimeBase.h
Normal file
234
driver/PublicUtility/CAHostTimeBase.h
Normal file
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
File: CAHostTimeBase.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAHostTimeBase_h__)
|
||||
#define __CAHostTimeBase_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <mach/mach_time.h>
|
||||
#include <pthread.h>
|
||||
#elif TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#include "WinPThreadDefs.h"
|
||||
#else
|
||||
#error Unsupported operating system
|
||||
#endif
|
||||
|
||||
#include "CADebugPrintf.h"
|
||||
|
||||
//=============================================================================
|
||||
// CAHostTimeBase
|
||||
//
|
||||
// This class provides platform independent access to the host's time base.
|
||||
//=============================================================================
|
||||
|
||||
#if CoreAudio_Debug
|
||||
// #define Log_Host_Time_Base_Parameters 1
|
||||
// #define Track_Host_TimeBase 1
|
||||
#endif
|
||||
|
||||
class CAHostTimeBase
|
||||
{
|
||||
|
||||
public:
|
||||
static UInt64 ConvertToNanos(UInt64 inHostTime);
|
||||
static UInt64 ConvertFromNanos(UInt64 inNanos);
|
||||
|
||||
static UInt64 GetTheCurrentTime();
|
||||
#if TARGET_OS_MAC
|
||||
static UInt64 GetCurrentTime() { return GetTheCurrentTime(); }
|
||||
#endif
|
||||
static UInt64 GetCurrentTimeInNanos();
|
||||
|
||||
static Float64 GetFrequency() { pthread_once(&sIsInited, Initialize); return sFrequency; }
|
||||
static Float64 GetInverseFrequency() { pthread_once(&sIsInited, Initialize); return sInverseFrequency; }
|
||||
static UInt32 GetMinimumDelta() { pthread_once(&sIsInited, Initialize); return sMinDelta; }
|
||||
|
||||
static UInt64 AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
|
||||
static SInt64 HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime);
|
||||
|
||||
static UInt64 MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator);
|
||||
|
||||
private:
|
||||
static void Initialize();
|
||||
|
||||
static pthread_once_t sIsInited;
|
||||
|
||||
static Float64 sFrequency;
|
||||
static Float64 sInverseFrequency;
|
||||
static UInt32 sMinDelta;
|
||||
static UInt32 sToNanosNumerator;
|
||||
static UInt32 sToNanosDenominator;
|
||||
#if Track_Host_TimeBase
|
||||
static UInt64 sLastTime;
|
||||
#endif
|
||||
};
|
||||
|
||||
inline UInt64 CAHostTimeBase::GetTheCurrentTime()
|
||||
{
|
||||
UInt64 theTime = 0;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
theTime = mach_absolute_time();
|
||||
#elif TARGET_OS_WIN32
|
||||
LARGE_INTEGER theValue;
|
||||
QueryPerformanceCounter(&theValue);
|
||||
theTime = *((UInt64*)&theValue);
|
||||
#endif
|
||||
|
||||
#if Track_Host_TimeBase
|
||||
if(sLastTime != 0)
|
||||
{
|
||||
if(theTime <= sLastTime)
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::GetTheCurrentTime: the current time is earlier than the last time, now: %qd, then: %qd", theTime, sLastTime);
|
||||
}
|
||||
sLastTime = theTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
sLastTime = theTime;
|
||||
}
|
||||
#endif
|
||||
|
||||
return theTime;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::ConvertToNanos(UInt64 inHostTime)
|
||||
{
|
||||
pthread_once(&sIsInited, Initialize);
|
||||
|
||||
UInt64 theAnswer = MultiplyByRatio(inHostTime, sToNanosNumerator, sToNanosDenominator);
|
||||
#if CoreAudio_Debug
|
||||
if(((sToNanosNumerator > sToNanosDenominator) && (theAnswer < inHostTime)) || ((sToNanosDenominator > sToNanosNumerator) && (theAnswer > inHostTime)))
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::ConvertToNanos: The conversion wrapped");
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::ConvertFromNanos(UInt64 inNanos)
|
||||
{
|
||||
pthread_once(&sIsInited, Initialize);
|
||||
|
||||
UInt64 theAnswer = MultiplyByRatio(inNanos, sToNanosDenominator, sToNanosNumerator);
|
||||
#if CoreAudio_Debug
|
||||
if(((sToNanosDenominator > sToNanosNumerator) && (theAnswer < inNanos)) || ((sToNanosNumerator > sToNanosDenominator) && (theAnswer > inNanos)))
|
||||
{
|
||||
DebugPrintf("CAHostTimeBase::ConvertFromNanos: The conversion wrapped");
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::GetCurrentTimeInNanos()
|
||||
{
|
||||
return ConvertToNanos(GetTheCurrentTime());
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::AbsoluteHostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
|
||||
{
|
||||
UInt64 theAnswer;
|
||||
|
||||
if(inStartTime <= inEndTime)
|
||||
{
|
||||
theAnswer = inEndTime - inStartTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
theAnswer = inStartTime - inEndTime;
|
||||
}
|
||||
|
||||
return ConvertToNanos(theAnswer);
|
||||
}
|
||||
|
||||
inline SInt64 CAHostTimeBase::HostDeltaToNanos(UInt64 inStartTime, UInt64 inEndTime)
|
||||
{
|
||||
SInt64 theAnswer;
|
||||
SInt64 theSign = 1;
|
||||
|
||||
if(inStartTime <= inEndTime)
|
||||
{
|
||||
theAnswer = static_cast<SInt64>(inEndTime - inStartTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
theAnswer = static_cast<SInt64>(inStartTime - inEndTime);
|
||||
theSign = -1;
|
||||
}
|
||||
|
||||
return theSign * static_cast<SInt64>(ConvertToNanos(static_cast<UInt64>(theAnswer)));
|
||||
}
|
||||
|
||||
inline UInt64 CAHostTimeBase::MultiplyByRatio(UInt64 inMuliplicand, UInt32 inNumerator, UInt32 inDenominator)
|
||||
{
|
||||
#if TARGET_OS_MAC && TARGET_RT_64_BIT
|
||||
__uint128_t theAnswer = inMuliplicand;
|
||||
#else
|
||||
long double theAnswer = inMuliplicand;
|
||||
#endif
|
||||
if(inNumerator != inDenominator)
|
||||
{
|
||||
theAnswer *= inNumerator;
|
||||
theAnswer /= inDenominator;
|
||||
}
|
||||
return static_cast<UInt64>(theAnswer);
|
||||
}
|
||||
|
||||
#endif
|
||||
345
driver/PublicUtility/CAMutex.cpp
Normal file
345
driver/PublicUtility/CAMutex.cpp
Normal file
@@ -0,0 +1,345 @@
|
||||
/*
|
||||
File: CAMutex.cpp
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CAMutex.h"
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAException.h"
|
||||
#include "CAHostTimeBase.h"
|
||||
|
||||
//==================================================================================================
|
||||
// Logging
|
||||
//==================================================================================================
|
||||
|
||||
#if CoreAudio_Debug
|
||||
// #define Log_Ownership 1
|
||||
// #define Log_Errors 1
|
||||
// #define Log_LongLatencies 1
|
||||
// #define LongLatencyThreshholdNS 1000000ULL // nanoseconds
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// CAMutex
|
||||
//==================================================================================================
|
||||
|
||||
CAMutex::CAMutex(const char* inName)
|
||||
:
|
||||
mName(inName),
|
||||
mOwner(0)
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
OSStatus theError = pthread_mutex_init(&mMutex, NULL);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::CAMutex: Could not init the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::CAMutex: creating %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
#elif TARGET_OS_WIN32
|
||||
mMutex = CreateMutex(NULL, false, NULL);
|
||||
ThrowIfNULL(mMutex, CAException(GetLastError()), "CAMutex::CAMutex: could not create the mutex.");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::CAMutex: creating %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
CAMutex::~CAMutex()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::~CAMutex: destroying %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
#elif TARGET_OS_WIN32
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::~CAMutex: destroying %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), mName, mOwner);
|
||||
#endif
|
||||
if(mMutex != NULL)
|
||||
{
|
||||
CloseHandle(mMutex);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CAMutex::Lock()
|
||||
{
|
||||
bool theAnswer = false;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t theCurrentThread = pthread_self();
|
||||
if(!pthread_equal(theCurrentThread, mOwner))
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p is locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
|
||||
#if Log_LongLatencies
|
||||
UInt64 lockTryTime = CAHostTimeBase::GetCurrentTimeInNanos();
|
||||
#endif
|
||||
|
||||
OSStatus theError = pthread_mutex_lock(&mMutex);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::Lock: Could not lock the mutex");
|
||||
mOwner = theCurrentThread;
|
||||
theAnswer = true;
|
||||
|
||||
#if Log_LongLatencies
|
||||
UInt64 lockAcquireTime = CAHostTimeBase::GetCurrentTimeInNanos();
|
||||
if (lockAcquireTime - lockTryTime >= LongLatencyThresholdNS)
|
||||
DebugPrintfRtn(DebugPrintfFileComma "Thread %p took %.6fs to acquire the lock %s\n", theCurrentThread, (lockAcquireTime - lockTryTime) * 1.0e-9 /* nanos to seconds */, mName);
|
||||
#endif
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Lock: thread %p has locked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner != GetCurrentThreadId())
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu is locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
OSStatus theError = WaitForSingleObject(mMutex, INFINITE);
|
||||
ThrowIfError(theError, CAException(theError), "CAMutex::Lock: could not lock the mutex");
|
||||
mOwner = GetCurrentThreadId();
|
||||
theAnswer = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Lock: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CAMutex::Unlock()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
if(pthread_equal(pthread_self(), mOwner))
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p is unlocking %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
mOwner = 0;
|
||||
OSStatus theError = pthread_mutex_unlock(&mMutex);
|
||||
ThrowIf(theError != 0, CAException(theError), "CAMutex::Unlock: Could not unlock the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Unlock: thread %p has unlocked %s, owner: %p\n", pthread_self(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), pthread_self(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner == GetCurrentThreadId())
|
||||
{
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu is unlocking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
mOwner = 0;
|
||||
bool wasReleased = ReleaseMutex(mMutex);
|
||||
ThrowIf(!wasReleased, CAException(GetLastError()), "CAMutex::Unlock: Could not unlock the mutex");
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Unlock: thread %lu has unlocked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage("CAMutex::Unlock: A thread is attempting to unlock a Mutex it doesn't own");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CAMutex::Try(bool& outWasLocked)
|
||||
{
|
||||
bool theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t theCurrentThread = pthread_self();
|
||||
if(!pthread_equal(theCurrentThread, mOwner))
|
||||
{
|
||||
// this means the current thread doesn't already own the lock
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p is try-locking %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
|
||||
// go ahead and call trylock to see if we can lock it.
|
||||
int theError = pthread_mutex_trylock(&mMutex);
|
||||
if(theError == 0)
|
||||
{
|
||||
// return value of 0 means we successfully locked the lock
|
||||
mOwner = theCurrentThread;
|
||||
theAnswer = true;
|
||||
outWasLocked = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p has locked %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else if(theError == EBUSY)
|
||||
{
|
||||
// return value of EBUSY means that the lock was already locked by another thread
|
||||
theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%p %.4f: CAMutex::Try: thread %p failed to lock %s, owner: %p\n", theCurrentThread, ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), theCurrentThread, mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// any other return value means something really bad happenned
|
||||
ThrowIfError(theError, CAException(theError), "CAMutex::Try: call to pthread_mutex_trylock failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means the current thread already owns the lock
|
||||
theAnswer = true;
|
||||
outWasLocked = false;
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mOwner != GetCurrentThreadId())
|
||||
{
|
||||
// this means the current thread doesn't own the lock
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu is try-locking %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
|
||||
// try to acquire the mutex
|
||||
OSStatus theError = WaitForSingleObject(mMutex, 0);
|
||||
if(theError == WAIT_OBJECT_0)
|
||||
{
|
||||
// this means we successfully locked the lock
|
||||
mOwner = GetCurrentThreadId();
|
||||
theAnswer = true;
|
||||
outWasLocked = true;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu has locked %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else if(theError == WAIT_TIMEOUT)
|
||||
{
|
||||
// this means that the lock was already locked by another thread
|
||||
theAnswer = false;
|
||||
outWasLocked = false;
|
||||
|
||||
#if Log_Ownership
|
||||
DebugPrintfRtn(DebugPrintfFileComma "%lu %.4f: CAMutex::Try: thread %lu failed to lock %s, owner: %lu\n", GetCurrentThreadId(), ((Float64)(CAHostTimeBase::GetCurrentTimeInNanos()) / 1000000.0), GetCurrentThreadId(), mName, mOwner);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// any other return value means something really bad happenned
|
||||
ThrowIfError(theError, CAException(GetLastError()), "CAMutex::Try: call to lock the mutex failed");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this means the current thread already owns the lock
|
||||
theAnswer = true;
|
||||
outWasLocked = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
bool CAMutex::IsFree() const
|
||||
{
|
||||
return mOwner == 0;
|
||||
}
|
||||
|
||||
bool CAMutex::IsOwnedByCurrentThread() const
|
||||
{
|
||||
bool theAnswer = true;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
theAnswer = pthread_equal(pthread_self(), mOwner);
|
||||
#elif TARGET_OS_WIN32
|
||||
theAnswer = (mOwner == GetCurrentThreadId());
|
||||
#endif
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
|
||||
CAMutex::Unlocker::Unlocker(CAMutex& inMutex)
|
||||
: mMutex(inMutex),
|
||||
mNeedsLock(false)
|
||||
{
|
||||
Assert(mMutex.IsOwnedByCurrentThread(), "Major problem: Unlocker attempted to unlock a mutex not owned by the current thread!");
|
||||
|
||||
mMutex.Unlock();
|
||||
mNeedsLock = true;
|
||||
}
|
||||
|
||||
CAMutex::Unlocker::~Unlocker()
|
||||
{
|
||||
if(mNeedsLock)
|
||||
{
|
||||
mMutex.Lock();
|
||||
}
|
||||
}
|
||||
164
driver/PublicUtility/CAMutex.h
Normal file
164
driver/PublicUtility/CAMutex.h
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
File: CAMutex.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#ifndef __CAMutex_h__
|
||||
#define __CAMutex_h__
|
||||
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <pthread.h>
|
||||
#elif TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#error Unsupported operating system
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// A recursive mutex.
|
||||
//==================================================================================================
|
||||
|
||||
class CAMutex
|
||||
{
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAMutex(const char* inName);
|
||||
virtual ~CAMutex();
|
||||
|
||||
// Actions
|
||||
public:
|
||||
virtual bool Lock();
|
||||
virtual void Unlock();
|
||||
virtual bool Try(bool& outWasLocked); // returns true if lock is free, false if not
|
||||
|
||||
virtual bool IsFree() const;
|
||||
virtual bool IsOwnedByCurrentThread() const;
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
const char* mName;
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t mOwner;
|
||||
pthread_mutex_t mMutex;
|
||||
#elif TARGET_OS_WIN32
|
||||
UInt32 mOwner;
|
||||
HANDLE mMutex;
|
||||
#endif
|
||||
|
||||
// Helper class to manage taking and releasing recursively
|
||||
public:
|
||||
class Locker
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
Locker(CAMutex& inMutex) : mMutex(&inMutex), mNeedsRelease(false) { mNeedsRelease = mMutex->Lock(); }
|
||||
Locker(const CAMutex& inMutex) : mMutex(const_cast<CAMutex*>(&inMutex)), mNeedsRelease(false) { mNeedsRelease = mMutex->Lock(); }
|
||||
Locker(CAMutex* inMutex) : mMutex(inMutex), mNeedsRelease(false) { mNeedsRelease = (mMutex != NULL && mMutex->Lock()); }
|
||||
// in this case the mutex can be null
|
||||
~Locker() { if(mNeedsRelease) { mMutex->Unlock(); } }
|
||||
|
||||
|
||||
private:
|
||||
Locker(const Locker&);
|
||||
Locker& operator=(const Locker&);
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CAMutex* mMutex;
|
||||
bool mNeedsRelease;
|
||||
|
||||
};
|
||||
|
||||
// Unlocker
|
||||
class Unlocker
|
||||
{
|
||||
public:
|
||||
Unlocker(CAMutex& inMutex);
|
||||
~Unlocker();
|
||||
|
||||
private:
|
||||
CAMutex& mMutex;
|
||||
bool mNeedsLock;
|
||||
|
||||
// Hidden definitions of copy ctor, assignment operator
|
||||
Unlocker(const Unlocker& copy); // Not implemented
|
||||
Unlocker& operator=(const Unlocker& copy); // Not implemented
|
||||
};
|
||||
|
||||
// you can use this with Try - if you take the lock in try, pass in the outWasLocked var
|
||||
class Tryer {
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
Tryer (CAMutex &mutex) : mMutex(mutex), mNeedsRelease(false), mHasLock(false) { mHasLock = mMutex.Try (mNeedsRelease); }
|
||||
~Tryer () { if (mNeedsRelease) mMutex.Unlock(); }
|
||||
|
||||
bool HasLock () const { return mHasLock; }
|
||||
|
||||
private:
|
||||
Tryer(const Tryer&);
|
||||
Tryer& operator=(const Tryer&);
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
CAMutex & mMutex;
|
||||
bool mNeedsRelease;
|
||||
bool mHasLock;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif // __CAMutex_h__
|
||||
450
driver/PublicUtility/CAPThread.cpp
Normal file
450
driver/PublicUtility/CAPThread.cpp
Normal file
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
File: CAPThread.cpp
|
||||
Abstract: CAPThread.h
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
// Self Include
|
||||
#include "CAPThread.h"
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CADebugMacros.h"
|
||||
#include "CAException.h"
|
||||
|
||||
// System Includes
|
||||
#if TARGET_OS_MAC
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
|
||||
// Standard Library Includes
|
||||
#include <stdio.h>
|
||||
|
||||
//==================================================================================================
|
||||
// CAPThread
|
||||
//==================================================================================================
|
||||
|
||||
// returns the thread's priority as it was last set by the API
|
||||
#define CAPTHREAD_SET_PRIORITY 0
|
||||
// returns the thread's priority as it was last scheduled by the Kernel
|
||||
#define CAPTHREAD_SCHEDULED_PRIORITY 1
|
||||
|
||||
//#define Log_SetPriority 1
|
||||
|
||||
CAPThread::CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPriority, bool inFixedPriority, bool inAutoDelete, const char* inThreadName)
|
||||
:
|
||||
#if TARGET_OS_MAC
|
||||
mPThread(0),
|
||||
mSpawningThreadPriority(getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY)),
|
||||
#elif TARGET_OS_WIN32
|
||||
mThreadHandle(NULL),
|
||||
mThreadID(0),
|
||||
#endif
|
||||
mThreadRoutine(inThreadRoutine),
|
||||
mThreadParameter(inParameter),
|
||||
mPriority(inPriority),
|
||||
mPeriod(0),
|
||||
mComputation(0),
|
||||
mConstraint(0),
|
||||
mIsPreemptible(true),
|
||||
mTimeConstraintSet(false),
|
||||
mFixedPriority(inFixedPriority),
|
||||
mAutoDelete(inAutoDelete)
|
||||
{
|
||||
if(inThreadName != NULL)
|
||||
{
|
||||
strlcpy(mThreadName, inThreadName, kMaxThreadNameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(mThreadName, 0, kMaxThreadNameLength);
|
||||
}
|
||||
}
|
||||
|
||||
CAPThread::CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible, bool inAutoDelete, const char* inThreadName)
|
||||
:
|
||||
#if TARGET_OS_MAC
|
||||
mPThread(0),
|
||||
mSpawningThreadPriority(getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY)),
|
||||
#elif TARGET_OS_WIN32
|
||||
mThreadHandle(NULL),
|
||||
mThreadID(0),
|
||||
#endif
|
||||
mThreadRoutine(inThreadRoutine),
|
||||
mThreadParameter(inParameter),
|
||||
mPriority(kDefaultThreadPriority),
|
||||
mPeriod(inPeriod),
|
||||
mComputation(inComputation),
|
||||
mConstraint(inConstraint),
|
||||
mIsPreemptible(inIsPreemptible),
|
||||
mTimeConstraintSet(true),
|
||||
mFixedPriority(false),
|
||||
mAutoDelete(inAutoDelete)
|
||||
{
|
||||
if(inThreadName != NULL)
|
||||
{
|
||||
strlcpy(mThreadName, inThreadName, kMaxThreadNameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(mThreadName, 0, kMaxThreadNameLength);
|
||||
}
|
||||
}
|
||||
|
||||
CAPThread::~CAPThread()
|
||||
{
|
||||
}
|
||||
|
||||
UInt32 CAPThread::GetScheduledPriority()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
return CAPThread::getScheduledPriority( mPThread, CAPTHREAD_SCHEDULED_PRIORITY );
|
||||
#elif TARGET_OS_WIN32
|
||||
UInt32 theAnswer = 0;
|
||||
if(mThreadHandle != NULL)
|
||||
{
|
||||
theAnswer = GetThreadPriority(mThreadHandle);
|
||||
}
|
||||
return theAnswer;
|
||||
#endif
|
||||
}
|
||||
|
||||
UInt32 CAPThread::GetScheduledPriority(NativeThread thread)
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
return getScheduledPriority( thread, CAPTHREAD_SCHEDULED_PRIORITY );
|
||||
#elif TARGET_OS_WIN32
|
||||
return 0; // ???
|
||||
#endif
|
||||
}
|
||||
|
||||
void CAPThread::SetPriority(UInt32 inPriority, bool inFixedPriority)
|
||||
{
|
||||
mPriority = inPriority;
|
||||
mTimeConstraintSet = false;
|
||||
mFixedPriority = inFixedPriority;
|
||||
#if TARGET_OS_MAC
|
||||
if(mPThread != 0)
|
||||
{
|
||||
SetPriority(mPThread, mPriority, mFixedPriority);
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mThreadID != NULL)
|
||||
{
|
||||
SetPriority(mThreadID, mPriority, mFixedPriority);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CAPThread::SetPriority(NativeThread inThread, UInt32 inPriority, bool inFixedPriority)
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
if(inThread != 0)
|
||||
{
|
||||
kern_return_t theError = 0;
|
||||
|
||||
// set whether or not this is a fixed priority thread
|
||||
if (inFixedPriority)
|
||||
{
|
||||
thread_extended_policy_data_t theFixedPolicy = { false };
|
||||
theError = thread_policy_set(pthread_mach_thread_np(inThread), THREAD_EXTENDED_POLICY, (thread_policy_t)&theFixedPolicy, THREAD_EXTENDED_POLICY_COUNT);
|
||||
AssertNoKernelError(theError, "CAPThread::SetPriority: failed to set the fixed-priority policy");
|
||||
}
|
||||
|
||||
// set the thread's absolute priority which is relative to the priority on which thread_policy_set() is called
|
||||
UInt32 theCurrentThreadPriority = getScheduledPriority(pthread_self(), CAPTHREAD_SET_PRIORITY);
|
||||
thread_precedence_policy_data_t thePrecedencePolicy = { static_cast<integer_t>(inPriority - theCurrentThreadPriority) };
|
||||
theError = thread_policy_set(pthread_mach_thread_np(inThread), THREAD_PRECEDENCE_POLICY, (thread_policy_t)&thePrecedencePolicy, THREAD_PRECEDENCE_POLICY_COUNT);
|
||||
AssertNoKernelError(theError, "CAPThread::SetPriority: failed to set the precedence policy");
|
||||
|
||||
#if Log_SetPriority
|
||||
DebugMessageN4("CAPThread::SetPriority: requsted: %lu spawning: %lu current: %lu assigned: %d", mPriority, mSpawningThreadPriority, theCurrentThreadPriority, thePrecedencePolicy.importance);
|
||||
#endif
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(inThread != NULL)
|
||||
{
|
||||
HANDLE hThread = OpenThread(NULL, FALSE, inThread);
|
||||
if(hThread != NULL) {
|
||||
SetThreadPriority(hThread, inPriority);
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CAPThread::SetTimeConstraints(UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible)
|
||||
{
|
||||
mPeriod = inPeriod;
|
||||
mComputation = inComputation;
|
||||
mConstraint = inConstraint;
|
||||
mIsPreemptible = inIsPreemptible;
|
||||
mTimeConstraintSet = true;
|
||||
#if TARGET_OS_MAC
|
||||
if(mPThread != 0)
|
||||
{
|
||||
thread_time_constraint_policy_data_t thePolicy;
|
||||
thePolicy.period = mPeriod;
|
||||
thePolicy.computation = mComputation;
|
||||
thePolicy.constraint = mConstraint;
|
||||
thePolicy.preemptible = mIsPreemptible;
|
||||
AssertNoError(thread_policy_set(pthread_mach_thread_np(mPThread), THREAD_TIME_CONSTRAINT_POLICY, (thread_policy_t)&thePolicy, THREAD_TIME_CONSTRAINT_POLICY_COUNT), "CAPThread::SetTimeConstraints: thread_policy_set failed");
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
if(mThreadHandle != NULL)
|
||||
{
|
||||
SetThreadPriority(mThreadHandle, THREAD_PRIORITY_TIME_CRITICAL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CAPThread::Start()
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
Assert(mPThread == 0, "CAPThread::Start: can't start because the thread is already running");
|
||||
if(mPThread == 0)
|
||||
{
|
||||
OSStatus theResult;
|
||||
pthread_attr_t theThreadAttributes;
|
||||
|
||||
theResult = pthread_attr_init(&theThreadAttributes);
|
||||
ThrowIf(theResult != 0, CAException(theResult), "CAPThread::Start: Thread attributes could not be created.");
|
||||
|
||||
theResult = pthread_attr_setdetachstate(&theThreadAttributes, PTHREAD_CREATE_DETACHED);
|
||||
ThrowIf(theResult != 0, CAException(theResult), "CAPThread::Start: A thread could not be created in the detached state.");
|
||||
|
||||
theResult = pthread_create(&mPThread, &theThreadAttributes, (ThreadRoutine)CAPThread::Entry, this);
|
||||
ThrowIf(theResult != 0 || !mPThread, CAException(theResult), "CAPThread::Start: Could not create a thread.");
|
||||
|
||||
pthread_attr_destroy(&theThreadAttributes);
|
||||
|
||||
}
|
||||
#elif TARGET_OS_WIN32
|
||||
Assert(mThreadID == 0, "CAPThread::Start: can't start because the thread is already running");
|
||||
if(mThreadID == 0)
|
||||
{
|
||||
// clean up the existing thread handle
|
||||
if(mThreadHandle != NULL)
|
||||
{
|
||||
CloseHandle(mThreadHandle);
|
||||
mThreadHandle = NULL;
|
||||
}
|
||||
|
||||
// create a new thread
|
||||
mThreadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Entry, this, 0, &mThreadID);
|
||||
ThrowIf(mThreadHandle == NULL, CAException(GetLastError()), "CAPThread::Start: Could not create a thread.");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
|
||||
void* CAPThread::Entry(CAPThread* inCAPThread)
|
||||
{
|
||||
void* theAnswer = NULL;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
inCAPThread->mPThread = pthread_self();
|
||||
#elif TARGET_OS_WIN32
|
||||
// do we need to do something here?
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6)
|
||||
if(inCAPThread->mThreadName[0] != 0)
|
||||
{
|
||||
pthread_setname_np(inCAPThread->mThreadName);
|
||||
}
|
||||
#endif
|
||||
|
||||
try
|
||||
{
|
||||
if(inCAPThread->mTimeConstraintSet)
|
||||
{
|
||||
inCAPThread->SetTimeConstraints(inCAPThread->mPeriod, inCAPThread->mComputation, inCAPThread->mConstraint, inCAPThread->mIsPreemptible);
|
||||
}
|
||||
else
|
||||
{
|
||||
inCAPThread->SetPriority(inCAPThread->mPriority, inCAPThread->mFixedPriority);
|
||||
}
|
||||
|
||||
if(inCAPThread->mThreadRoutine != NULL)
|
||||
{
|
||||
theAnswer = inCAPThread->mThreadRoutine(inCAPThread->mThreadParameter);
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// what should be done here?
|
||||
}
|
||||
inCAPThread->mPThread = 0;
|
||||
if (inCAPThread->mAutoDelete)
|
||||
delete inCAPThread;
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
UInt32 CAPThread::getScheduledPriority(pthread_t inThread, int inPriorityKind)
|
||||
{
|
||||
thread_basic_info_data_t threadInfo;
|
||||
policy_info_data_t thePolicyInfo;
|
||||
unsigned int count;
|
||||
|
||||
if (inThread == NULL)
|
||||
return 0;
|
||||
|
||||
// get basic info
|
||||
count = THREAD_BASIC_INFO_COUNT;
|
||||
thread_info (pthread_mach_thread_np (inThread), THREAD_BASIC_INFO, (thread_info_t)&threadInfo, &count);
|
||||
|
||||
switch (threadInfo.policy) {
|
||||
case POLICY_TIMESHARE:
|
||||
count = POLICY_TIMESHARE_INFO_COUNT;
|
||||
thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_TIMESHARE_INFO, (thread_info_t)&(thePolicyInfo.ts), &count);
|
||||
if (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) {
|
||||
return static_cast<UInt32>(thePolicyInfo.ts.cur_priority);
|
||||
}
|
||||
return static_cast<UInt32>(thePolicyInfo.ts.base_priority);
|
||||
break;
|
||||
|
||||
case POLICY_FIFO:
|
||||
count = POLICY_FIFO_INFO_COUNT;
|
||||
thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_FIFO_INFO, (thread_info_t)&(thePolicyInfo.fifo), &count);
|
||||
if ( (thePolicyInfo.fifo.depressed) && (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) ) {
|
||||
return static_cast<UInt32>(thePolicyInfo.fifo.depress_priority);
|
||||
}
|
||||
return static_cast<UInt32>(thePolicyInfo.fifo.base_priority);
|
||||
break;
|
||||
|
||||
case POLICY_RR:
|
||||
count = POLICY_RR_INFO_COUNT;
|
||||
thread_info(pthread_mach_thread_np (inThread), THREAD_SCHED_RR_INFO, (thread_info_t)&(thePolicyInfo.rr), &count);
|
||||
if ( (thePolicyInfo.rr.depressed) && (inPriorityKind == CAPTHREAD_SCHEDULED_PRIORITY) ) {
|
||||
return static_cast<UInt32>(thePolicyInfo.rr.depress_priority);
|
||||
}
|
||||
return static_cast<UInt32>(thePolicyInfo.rr.base_priority);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#elif TARGET_OS_WIN32
|
||||
|
||||
UInt32 WINAPI CAPThread::Entry(CAPThread* inCAPThread)
|
||||
{
|
||||
UInt32 theAnswer = 0;
|
||||
|
||||
try
|
||||
{
|
||||
if(inCAPThread->mTimeConstraintSet)
|
||||
{
|
||||
inCAPThread->SetTimeConstraints(inCAPThread->mPeriod, inCAPThread->mComputation, inCAPThread->mConstraint, inCAPThread->mIsPreemptible);
|
||||
}
|
||||
else
|
||||
{
|
||||
inCAPThread->SetPriority(inCAPThread->mPriority, inCAPThread->mFixedPriority);
|
||||
}
|
||||
|
||||
if(inCAPThread->mThreadRoutine != NULL)
|
||||
{
|
||||
theAnswer = reinterpret_cast<UInt32>(inCAPThread->mThreadRoutine(inCAPThread->mThreadParameter));
|
||||
}
|
||||
inCAPThread->mThreadID = 0;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
// what should be done here?
|
||||
}
|
||||
CloseHandle(inCAPThread->mThreadHandle);
|
||||
inCAPThread->mThreadHandle = NULL;
|
||||
if (inCAPThread->mAutoDelete)
|
||||
delete inCAPThread;
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
Boolean CompareAndSwap(UInt32 inOldValue, UInt32 inNewValue, UInt32* inOldValuePtr)
|
||||
{
|
||||
return InterlockedCompareExchange((volatile LONG*)inOldValuePtr, inNewValue, inOldValue) == inOldValue;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void CAPThread::SetName(const char* inThreadName)
|
||||
{
|
||||
if(inThreadName != NULL)
|
||||
{
|
||||
strlcpy(mThreadName, inThreadName, kMaxThreadNameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(mThreadName, 0, kMaxThreadNameLength);
|
||||
}
|
||||
}
|
||||
|
||||
#if CoreAudio_Debug
|
||||
void CAPThread::DebugPriority(const char *label)
|
||||
{
|
||||
#if !TARGET_OS_WIN32
|
||||
if (mTimeConstraintSet)
|
||||
printf("CAPThread::%s %p: pri=<time constraint>, spawning pri=%d, scheduled pri=%d\n", label, this,
|
||||
(int)mSpawningThreadPriority, (mPThread != NULL) ? (int)GetScheduledPriority() : -1);
|
||||
else
|
||||
printf("CAPThread::%s %p: pri=%d%s, spawning pri=%d, scheduled pri=%d\n", label, this, (int)mPriority, mFixedPriority ? " fixed" : "",
|
||||
(int)mSpawningThreadPriority, (mPThread != NULL) ? (int)GetScheduledPriority() : -1);
|
||||
#else
|
||||
if (mTimeConstraintSet)
|
||||
{
|
||||
printf("CAPThread::%s %p: pri=<time constraint>, spawning pri=%d, scheduled pri=%d\n", label, this,
|
||||
(int)mPriority, (mThreadHandle != NULL) ? (int)GetScheduledPriority() : -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("CAPThread::%s %p: pri=%d%s, spawning pri=%d, scheduled pri=%d\n", label, this, (int)mPriority, mFixedPriority ? " fixed" : "",
|
||||
(int)mPriority, (mThreadHandle != NULL) ? (int)GetScheduledPriority() : -1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
191
driver/PublicUtility/CAPThread.h
Normal file
191
driver/PublicUtility/CAPThread.h
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
File: CAPThread.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAPThread_h__)
|
||||
#define __CAPThread_h__
|
||||
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// System Includes
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreFoundation/CFBase.h>
|
||||
#else
|
||||
#include <CFBase.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#elif TARGET_OS_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#error Unsupported operating system
|
||||
#endif
|
||||
|
||||
//==================================================================================================
|
||||
// CAPThread
|
||||
//
|
||||
// This class wraps a pthread and a Win32 thread.
|
||||
// caution: long-running fixed priority threads can make the system unresponsive
|
||||
//==================================================================================================
|
||||
|
||||
class CAPThread
|
||||
{
|
||||
|
||||
// Types
|
||||
public:
|
||||
typedef void* (*ThreadRoutine)(void* inParameter);
|
||||
|
||||
// Constants
|
||||
public:
|
||||
enum
|
||||
{
|
||||
#if TARGET_OS_MAC
|
||||
kMinThreadPriority = 1,
|
||||
kMaxThreadPriority = 63,
|
||||
kDefaultThreadPriority = 31,
|
||||
kMaxThreadNameLength = 64
|
||||
#elif TARGET_OS_WIN32
|
||||
kMinThreadPriority = 1,
|
||||
kMaxThreadPriority = 31,
|
||||
kDefaultThreadPriority = THREAD_PRIORITY_NORMAL,
|
||||
kMaxThreadNameLength = 256
|
||||
#endif
|
||||
};
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPriority = kDefaultThreadPriority, bool inFixedPriority=false, bool inAutoDelete=false, const char* inThreadName = NULL);
|
||||
CAPThread(ThreadRoutine inThreadRoutine, void* inParameter, UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible, bool inAutoDelete=false, const char* inThreadName = NULL);
|
||||
virtual ~CAPThread();
|
||||
|
||||
// Properties
|
||||
public:
|
||||
#if TARGET_OS_MAC
|
||||
typedef pthread_t NativeThread;
|
||||
|
||||
NativeThread GetNativeThread() { return mPThread; }
|
||||
static NativeThread GetCurrentThread() { return pthread_self(); }
|
||||
static bool IsNativeThreadsEqual(NativeThread a, NativeThread b) { return (a==b); }
|
||||
|
||||
bool operator==(NativeThread b) { return pthread_equal(mPThread,b); }
|
||||
|
||||
pthread_t GetPThread() const { return mPThread; }
|
||||
bool IsCurrentThread() const { return (0 != mPThread) && (pthread_self() == mPThread); }
|
||||
bool IsRunning() const { return 0 != mPThread; }
|
||||
static UInt32 getScheduledPriority(pthread_t inThread, int inPriorityKind);
|
||||
#elif TARGET_OS_WIN32
|
||||
typedef unsigned long NativeThread;
|
||||
|
||||
NativeThread GetNativeThread() { return mThreadID; }
|
||||
static NativeThread GetCurrentThread() { return GetCurrentThreadId(); }
|
||||
static bool IsNativeThreadsEqual(NativeThread a, NativeThread b) { return (a==b); }
|
||||
|
||||
bool operator ==(NativeThread b) { return (mThreadID==b); }
|
||||
|
||||
HANDLE GetThreadHandle() const { return mThreadHandle; }
|
||||
UInt32 GetThreadID() const { return mThreadID; }
|
||||
bool IsCurrentThread() const { return (0 != mThreadID) && (GetCurrentThreadId() == mThreadID); }
|
||||
bool IsRunning() const { return 0 != mThreadID; }
|
||||
#endif
|
||||
|
||||
bool IsTimeShareThread() const { return !mTimeConstraintSet; }
|
||||
bool IsTimeConstraintThread() const { return mTimeConstraintSet; }
|
||||
|
||||
UInt32 GetPriority() const { return mPriority; }
|
||||
UInt32 GetScheduledPriority();
|
||||
static UInt32 GetScheduledPriority(NativeThread thread);
|
||||
void SetPriority(UInt32 inPriority, bool inFixedPriority=false);
|
||||
static void SetPriority(NativeThread inThread, UInt32 inPriority, bool inFixedPriority = false);
|
||||
|
||||
void GetTimeConstraints(UInt32& outPeriod, UInt32& outComputation, UInt32& outConstraint, bool& outIsPreemptible) const { outPeriod = mPeriod; outComputation = mComputation; outConstraint = mConstraint; outIsPreemptible = mIsPreemptible; }
|
||||
void SetTimeConstraints(UInt32 inPeriod, UInt32 inComputation, UInt32 inConstraint, bool inIsPreemptible);
|
||||
void ClearTimeConstraints() { SetPriority(mPriority); }
|
||||
|
||||
bool WillAutoDelete() const { return mAutoDelete; }
|
||||
void SetAutoDelete(bool b) { mAutoDelete = b; }
|
||||
|
||||
void SetName(const char* inThreadName);
|
||||
|
||||
#if CoreAudio_Debug
|
||||
void DebugPriority(const char *label);
|
||||
#endif
|
||||
|
||||
// Actions
|
||||
public:
|
||||
virtual void Start();
|
||||
|
||||
// Implementation
|
||||
protected:
|
||||
#if TARGET_OS_MAC
|
||||
static void* Entry(CAPThread* inCAPThread);
|
||||
#elif TARGET_OS_WIN32
|
||||
static UInt32 WINAPI Entry(CAPThread* inCAPThread);
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
pthread_t mPThread;
|
||||
UInt32 mSpawningThreadPriority;
|
||||
#elif TARGET_OS_WIN32
|
||||
HANDLE mThreadHandle;
|
||||
unsigned long mThreadID;
|
||||
#endif
|
||||
ThreadRoutine mThreadRoutine;
|
||||
void* mThreadParameter;
|
||||
char mThreadName[kMaxThreadNameLength];
|
||||
UInt32 mPriority;
|
||||
UInt32 mPeriod;
|
||||
UInt32 mComputation;
|
||||
UInt32 mConstraint;
|
||||
bool mIsPreemptible;
|
||||
bool mTimeConstraintSet;
|
||||
bool mFixedPriority;
|
||||
bool mAutoDelete; // delete self when thread terminates
|
||||
};
|
||||
|
||||
#endif
|
||||
321
driver/PublicUtility/CAPropertyAddress.h
Normal file
321
driver/PublicUtility/CAPropertyAddress.h
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
File: CAPropertyAddress.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAPropertyAddress_h__)
|
||||
#define __CAPropertyAddress_h__
|
||||
|
||||
//==================================================================================================
|
||||
// Includes
|
||||
//==================================================================================================
|
||||
|
||||
// PublicUtility Includes
|
||||
#include "CADebugMacros.h"
|
||||
|
||||
// System Includes
|
||||
#include <CoreAudio/AudioHardware.h>
|
||||
|
||||
// Standard Library Includes
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
//==================================================================================================
|
||||
// CAPropertyAddress
|
||||
//
|
||||
// CAPropertyAddress extends the AudioObjectPropertyAddress structure to C++ including constructors
|
||||
// and other utility operations. Note that there is no defined operator< or operator== because the
|
||||
// presence of wildcards for the fields make comparisons ambiguous without specifying whether or
|
||||
// not to take the wildcards into account. Consequently, if you want to use this struct in an STL
|
||||
// data structure, you'll need to specify the approriate function object explicitly in the template
|
||||
// declaration.
|
||||
//==================================================================================================
|
||||
|
||||
struct CAPropertyAddress
|
||||
:
|
||||
public AudioObjectPropertyAddress
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAPropertyAddress() : AudioObjectPropertyAddress() { mSelector = 0; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
|
||||
CAPropertyAddress(AudioObjectPropertySelector inSelector) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = kAudioObjectPropertyScopeGlobal; mElement = kAudioObjectPropertyElementMaster; }
|
||||
CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = kAudioObjectPropertyElementMaster; }
|
||||
CAPropertyAddress(AudioObjectPropertySelector inSelector, AudioObjectPropertyScope inScope, AudioObjectPropertyElement inElement) : AudioObjectPropertyAddress() { mSelector = inSelector; mScope = inScope; mElement = inElement; }
|
||||
CAPropertyAddress(const AudioObjectPropertyAddress& inAddress) : AudioObjectPropertyAddress(inAddress){}
|
||||
CAPropertyAddress(const CAPropertyAddress& inAddress) : AudioObjectPropertyAddress(inAddress){}
|
||||
CAPropertyAddress& operator=(const AudioObjectPropertyAddress& inAddress) { AudioObjectPropertyAddress::operator=(inAddress); return *this; }
|
||||
CAPropertyAddress& operator=(const CAPropertyAddress& inAddress) { AudioObjectPropertyAddress::operator=(inAddress); return *this; }
|
||||
|
||||
// Operations
|
||||
public:
|
||||
static bool IsSameAddress(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) { return (inAddress1.mScope == inAddress2.mScope) && (inAddress1.mSelector == inAddress2.mSelector) && (inAddress1.mElement == inAddress2.mElement); }
|
||||
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; }
|
||||
static bool IsCongruentSelector(AudioObjectPropertySelector inSelector1, AudioObjectPropertySelector inSelector2) { return (inSelector1 == inSelector2) || (inSelector1 == kAudioObjectPropertySelectorWildcard) || (inSelector2 == kAudioObjectPropertySelectorWildcard); }
|
||||
static bool IsCongruentScope(AudioObjectPropertyScope inScope1, AudioObjectPropertyScope inScope2) { return (inScope1 == inScope2) || (inScope1 == kAudioObjectPropertyScopeWildcard) || (inScope2 == kAudioObjectPropertyScopeWildcard); }
|
||||
static bool IsCongruentElement(AudioObjectPropertyElement inElement1, AudioObjectPropertyElement inElement2) { return (inElement1 == inElement2) || (inElement1 == kAudioObjectPropertyElementWildcard) || (inElement2 == kAudioObjectPropertyElementWildcard); }
|
||||
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); }
|
||||
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; }
|
||||
|
||||
// STL Helpers
|
||||
public:
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
struct EqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsSameAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
|
||||
struct LessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsLessThanAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
|
||||
struct CongruentEqualTo : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
|
||||
struct CongruentLessThan : public std::binary_function<AudioObjectPropertyAddress, AudioObjectPropertyAddress, bool>
|
||||
{
|
||||
bool operator()(const AudioObjectPropertyAddress& inAddress1, const AudioObjectPropertyAddress& inAddress2) const { return IsCongruentLessThanAddress(inAddress1, inAddress2); }
|
||||
};
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// CAPropertyAddressList
|
||||
//
|
||||
// An auto-resizing array of CAPropertyAddress structures.
|
||||
//==================================================================================================
|
||||
|
||||
class CAPropertyAddressList
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAPropertyAddressList() : mAddressList(), mToken(NULL) {}
|
||||
explicit CAPropertyAddressList(void* inToken) : mAddressList(), mToken(inToken) {}
|
||||
explicit CAPropertyAddressList(uintptr_t inToken) : mAddressList(), mToken(reinterpret_cast<void*>(inToken)) {}
|
||||
CAPropertyAddressList(const CAPropertyAddressList& inAddressList) : mAddressList(inAddressList.mAddressList), mToken(inAddressList.mToken) {}
|
||||
CAPropertyAddressList& operator=(const CAPropertyAddressList& inAddressList) { mAddressList = inAddressList.mAddressList; mToken = inAddressList.mToken; return *this; }
|
||||
~CAPropertyAddressList() {}
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void* GetToken() const { return mToken; }
|
||||
void SetToken(void* inToken) { mToken = inToken; }
|
||||
|
||||
uintptr_t GetIntToken() const { return reinterpret_cast<uintptr_t>(mToken); }
|
||||
void SetIntToken(uintptr_t inToken) { mToken = reinterpret_cast<void*>(inToken); }
|
||||
|
||||
AudioObjectID GetAudioObjectIDToken() const { return static_cast<AudioObjectID>(reinterpret_cast<uintptr_t>(mToken)); }
|
||||
|
||||
bool IsEmpty() const { return mAddressList.empty(); }
|
||||
UInt32 GetNumberItems() const { return ToUInt32(mAddressList.size()); }
|
||||
void GetItemByIndex(UInt32 inIndex, AudioObjectPropertyAddress& outAddress) const { if(inIndex < mAddressList.size()) { outAddress = mAddressList.at(inIndex); } }
|
||||
const AudioObjectPropertyAddress* GetItems() const { return &(*mAddressList.begin()); }
|
||||
AudioObjectPropertyAddress* GetItems() { return &(*mAddressList.begin()); }
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
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(); }
|
||||
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(); }
|
||||
#pragma clang diagnostic pop
|
||||
|
||||
void AppendItem(const AudioObjectPropertyAddress& inAddress) { mAddressList.push_back(inAddress); }
|
||||
void AppendUniqueItem(const AudioObjectPropertyAddress& inAddress) { if(!HasItem(inAddress)) { mAddressList.push_back(inAddress); } }
|
||||
void AppendUniqueExactItem(const AudioObjectPropertyAddress& inAddress) { if(!HasExactItem(inAddress)) { mAddressList.push_back(inAddress); } }
|
||||
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); } }
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated"
|
||||
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); } }
|
||||
#pragma clang diagnostic pop
|
||||
void EraseItemAtIndex(UInt32 inIndex) { if(inIndex < mAddressList.size()) { AddressList::iterator theIterator = mAddressList.begin(); std::advance(theIterator, static_cast<int>(inIndex)); mAddressList.erase(theIterator); } }
|
||||
void EraseAllItems() { mAddressList.clear(); }
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
typedef std::vector<CAPropertyAddress> AddressList;
|
||||
|
||||
AddressList mAddressList;
|
||||
void* mToken;
|
||||
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
// CAPropertyAddressListVector
|
||||
//
|
||||
// An auto-resizing array of CAPropertyAddressList objects.
|
||||
//==================================================================================================
|
||||
|
||||
class CAPropertyAddressListVector
|
||||
{
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAPropertyAddressListVector() : mAddressListVector() {}
|
||||
CAPropertyAddressListVector(const CAPropertyAddressListVector& inAddressListVector) : mAddressListVector(inAddressListVector.mAddressListVector) {}
|
||||
CAPropertyAddressListVector& operator=(const CAPropertyAddressListVector& inAddressListVector) { mAddressListVector = inAddressListVector.mAddressListVector; return *this; }
|
||||
~CAPropertyAddressListVector() {}
|
||||
|
||||
// Operations
|
||||
public:
|
||||
bool IsEmpty() const { return mAddressListVector.empty(); }
|
||||
bool HasAnyNonEmptyItems() const;
|
||||
bool HasAnyItemsWithAddress(const AudioObjectPropertyAddress& inAddress) const;
|
||||
bool HasAnyItemsWithExactAddress(const AudioObjectPropertyAddress& inAddress) const;
|
||||
|
||||
UInt32 GetNumberItems() const { return ToUInt32(mAddressListVector.size()); }
|
||||
const CAPropertyAddressList& GetItemByIndex(UInt32 inIndex) const { return mAddressListVector.at(inIndex); }
|
||||
CAPropertyAddressList& GetItemByIndex(UInt32 inIndex) { return mAddressListVector.at(inIndex); }
|
||||
const CAPropertyAddressList* GetItemByToken(void* inToken) const;
|
||||
CAPropertyAddressList* GetItemByToken(void* inToken);
|
||||
const CAPropertyAddressList* GetItemByIntToken(uintptr_t inToken) const;
|
||||
CAPropertyAddressList* GetItemByIntToken(uintptr_t inToken);
|
||||
|
||||
void AppendItem(const CAPropertyAddressList& inAddressList) { mAddressListVector.push_back(inAddressList); }
|
||||
void EraseAllItems() { mAddressListVector.clear(); }
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
typedef std::vector<CAPropertyAddressList> AddressListVector;
|
||||
|
||||
AddressListVector mAddressListVector;
|
||||
|
||||
};
|
||||
|
||||
inline bool CAPropertyAddressListVector::HasAnyNonEmptyItems() const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
|
||||
{
|
||||
theAnswer = !theIterator->IsEmpty();
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline bool CAPropertyAddressListVector::HasAnyItemsWithAddress(const AudioObjectPropertyAddress& inAddress) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
|
||||
{
|
||||
theAnswer = theIterator->HasItem(inAddress);
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline bool CAPropertyAddressListVector::HasAnyItemsWithExactAddress(const AudioObjectPropertyAddress& inAddress) const
|
||||
{
|
||||
bool theAnswer = false;
|
||||
for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !theAnswer && (theIterator != mAddressListVector.end()); ++theIterator)
|
||||
{
|
||||
theAnswer = theIterator->HasExactItem(inAddress);
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline const CAPropertyAddressList* CAPropertyAddressListVector::GetItemByToken(void* inToken) const
|
||||
{
|
||||
const CAPropertyAddressList* theAnswer = NULL;
|
||||
bool wasFound = false;
|
||||
for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
|
||||
{
|
||||
if(theIterator->GetToken() == inToken)
|
||||
{
|
||||
wasFound = true;
|
||||
theAnswer = &(*theIterator);
|
||||
}
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline CAPropertyAddressList* CAPropertyAddressListVector::GetItemByToken(void* inToken)
|
||||
{
|
||||
CAPropertyAddressList* theAnswer = NULL;
|
||||
bool wasFound = false;
|
||||
for(AddressListVector::iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
|
||||
{
|
||||
if(theIterator->GetToken() == inToken)
|
||||
{
|
||||
wasFound = true;
|
||||
theAnswer = &(*theIterator);
|
||||
}
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline const CAPropertyAddressList* CAPropertyAddressListVector::GetItemByIntToken(uintptr_t inToken) const
|
||||
{
|
||||
const CAPropertyAddressList* theAnswer = NULL;
|
||||
bool wasFound = false;
|
||||
for(AddressListVector::const_iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
|
||||
{
|
||||
if(theIterator->GetIntToken() == inToken)
|
||||
{
|
||||
wasFound = true;
|
||||
theAnswer = &(*theIterator);
|
||||
}
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
inline CAPropertyAddressList* CAPropertyAddressListVector::GetItemByIntToken(uintptr_t inToken)
|
||||
{
|
||||
CAPropertyAddressList* theAnswer = NULL;
|
||||
bool wasFound = false;
|
||||
for(AddressListVector::iterator theIterator = mAddressListVector.begin(); !wasFound && (theIterator != mAddressListVector.end()); ++theIterator)
|
||||
{
|
||||
if(theIterator->GetIntToken() == inToken)
|
||||
{
|
||||
wasFound = true;
|
||||
theAnswer = &(*theIterator);
|
||||
}
|
||||
}
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
#endif
|
||||
319
driver/PublicUtility/CARingBuffer.cpp
Normal file
319
driver/PublicUtility/CARingBuffer.cpp
Normal file
@@ -0,0 +1,319 @@
|
||||
/*
|
||||
File: CARingBuffer.cpp
|
||||
Abstract: CARingBuffer.h
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#include "CARingBuffer.h"
|
||||
#include "CABitOperations.h"
|
||||
#include "CAAutoDisposer.h"
|
||||
#include "CAAtomic.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <libkern/OSAtomic.h>
|
||||
|
||||
CARingBuffer::CARingBuffer() :
|
||||
mBuffers(NULL), mNumberChannels(0), mCapacityFrames(0), mCapacityBytes(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CARingBuffer::~CARingBuffer()
|
||||
{
|
||||
Deallocate();
|
||||
}
|
||||
|
||||
|
||||
void CARingBuffer::Allocate(int nChannels, UInt32 bytesPerFrame, UInt32 capacityFrames)
|
||||
{
|
||||
Deallocate();
|
||||
|
||||
capacityFrames = NextPowerOfTwo(capacityFrames);
|
||||
|
||||
mNumberChannels = nChannels;
|
||||
mBytesPerFrame = bytesPerFrame;
|
||||
mCapacityFrames = capacityFrames;
|
||||
mCapacityFramesMask = capacityFrames - 1;
|
||||
mCapacityBytes = bytesPerFrame * capacityFrames;
|
||||
|
||||
// put everything in one memory allocation, first the pointers, then the deinterleaved channels
|
||||
UInt32 allocSize = (mCapacityBytes + sizeof(Byte *)) * nChannels;
|
||||
Byte *p = (Byte *)CA_malloc(allocSize);
|
||||
memset(p, 0, allocSize);
|
||||
mBuffers = (Byte **)p;
|
||||
p += nChannels * sizeof(Byte *);
|
||||
for (int i = 0; i < nChannels; ++i) {
|
||||
mBuffers[i] = p;
|
||||
p += mCapacityBytes;
|
||||
}
|
||||
|
||||
for (UInt32 i = 0; i<kGeneralRingTimeBoundsQueueSize; ++i)
|
||||
{
|
||||
mTimeBoundsQueue[i].mStartTime = 0;
|
||||
mTimeBoundsQueue[i].mEndTime = 0;
|
||||
mTimeBoundsQueue[i].mUpdateCounter = 0;
|
||||
}
|
||||
mTimeBoundsQueuePtr = 0;
|
||||
}
|
||||
|
||||
void CARingBuffer::Deallocate()
|
||||
{
|
||||
if (mBuffers) {
|
||||
free(mBuffers);
|
||||
mBuffers = NULL;
|
||||
}
|
||||
mNumberChannels = 0;
|
||||
mCapacityBytes = 0;
|
||||
mCapacityFrames = 0;
|
||||
}
|
||||
|
||||
inline void ZeroRange(Byte **buffers, int nchannels, int offset, int nbytes)
|
||||
{
|
||||
while (--nchannels >= 0) {
|
||||
memset(*buffers + offset, 0, nbytes);
|
||||
++buffers;
|
||||
}
|
||||
}
|
||||
|
||||
inline void StoreABL(Byte **buffers, int destOffset, const AudioBufferList *abl, int srcOffset, int nbytes)
|
||||
{
|
||||
int nchannels = abl->mNumberBuffers;
|
||||
const AudioBuffer *src = abl->mBuffers;
|
||||
while (--nchannels >= 0) {
|
||||
if (srcOffset > (int)src->mDataByteSize) continue;
|
||||
memcpy(*buffers + destOffset, (Byte *)src->mData + srcOffset, std::min(nbytes, (int)src->mDataByteSize - srcOffset));
|
||||
++buffers;
|
||||
++src;
|
||||
}
|
||||
}
|
||||
|
||||
inline void FetchABL(AudioBufferList *abl, int destOffset, Byte **buffers, int srcOffset, int nbytes)
|
||||
{
|
||||
int nchannels = abl->mNumberBuffers;
|
||||
AudioBuffer *dest = abl->mBuffers;
|
||||
while (--nchannels >= 0) {
|
||||
if (destOffset > (int)dest->mDataByteSize) continue;
|
||||
memcpy((Byte *)dest->mData + destOffset, *buffers + srcOffset, std::min(nbytes, (int)dest->mDataByteSize - destOffset));
|
||||
++buffers;
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
inline void ZeroABL(AudioBufferList *abl, int destOffset, int nbytes)
|
||||
{
|
||||
int nBuffers = abl->mNumberBuffers;
|
||||
AudioBuffer *dest = abl->mBuffers;
|
||||
while (--nBuffers >= 0) {
|
||||
if (destOffset > (int)dest->mDataByteSize) continue;
|
||||
memset((Byte *)dest->mData + destOffset, 0, std::min(nbytes, (int)dest->mDataByteSize - destOffset));
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CARingBufferError CARingBuffer::Store(const AudioBufferList *abl, UInt32 framesToWrite, SampleTime startWrite)
|
||||
{
|
||||
if (framesToWrite == 0)
|
||||
return kCARingBufferError_OK;
|
||||
|
||||
if (framesToWrite > mCapacityFrames)
|
||||
return kCARingBufferError_TooMuch; // too big!
|
||||
|
||||
SampleTime endWrite = startWrite + framesToWrite;
|
||||
|
||||
if (startWrite < EndTime()) {
|
||||
// going backwards, throw everything out
|
||||
SetTimeBounds(startWrite, startWrite);
|
||||
} else if (endWrite - StartTime() <= mCapacityFrames) {
|
||||
// the buffer has not yet wrapped and will not need to
|
||||
} else {
|
||||
// advance the start time past the region we are about to overwrite
|
||||
SampleTime newStart = endWrite - mCapacityFrames; // one buffer of time behind where we're writing
|
||||
SampleTime newEnd = std::max(newStart, EndTime());
|
||||
SetTimeBounds(newStart, newEnd);
|
||||
}
|
||||
|
||||
// write the new frames
|
||||
Byte **buffers = mBuffers;
|
||||
int nchannels = mNumberChannels;
|
||||
int offset0, offset1, nbytes;
|
||||
SampleTime curEnd = EndTime();
|
||||
|
||||
if (startWrite > curEnd) {
|
||||
// we are skipping some samples, so zero the range we are skipping
|
||||
offset0 = FrameOffset(curEnd);
|
||||
offset1 = FrameOffset(startWrite);
|
||||
if (offset0 < offset1)
|
||||
ZeroRange(buffers, nchannels, offset0, offset1 - offset0);
|
||||
else {
|
||||
ZeroRange(buffers, nchannels, offset0, mCapacityBytes - offset0);
|
||||
ZeroRange(buffers, nchannels, 0, offset1);
|
||||
}
|
||||
offset0 = offset1;
|
||||
} else {
|
||||
offset0 = FrameOffset(startWrite);
|
||||
}
|
||||
|
||||
offset1 = FrameOffset(endWrite);
|
||||
if (offset0 < offset1)
|
||||
StoreABL(buffers, offset0, abl, 0, offset1 - offset0);
|
||||
else {
|
||||
nbytes = mCapacityBytes - offset0;
|
||||
StoreABL(buffers, offset0, abl, 0, nbytes);
|
||||
StoreABL(buffers, 0, abl, nbytes, offset1);
|
||||
}
|
||||
|
||||
// now update the end time
|
||||
SetTimeBounds(StartTime(), endWrite);
|
||||
|
||||
return kCARingBufferError_OK; // success
|
||||
}
|
||||
|
||||
void CARingBuffer::SetTimeBounds(SampleTime startTime, SampleTime endTime)
|
||||
{
|
||||
UInt32 nextPtr = mTimeBoundsQueuePtr + 1;
|
||||
UInt32 index = nextPtr & kGeneralRingTimeBoundsQueueMask;
|
||||
|
||||
mTimeBoundsQueue[index].mStartTime = startTime;
|
||||
mTimeBoundsQueue[index].mEndTime = endTime;
|
||||
mTimeBoundsQueue[index].mUpdateCounter = nextPtr;
|
||||
CAAtomicCompareAndSwap32Barrier(mTimeBoundsQueuePtr, mTimeBoundsQueuePtr + 1, (SInt32*)&mTimeBoundsQueuePtr);
|
||||
}
|
||||
|
||||
CARingBufferError CARingBuffer::GetTimeBounds(SampleTime &startTime, SampleTime &endTime)
|
||||
{
|
||||
for (int i=0; i<8; ++i) // fail after a few tries.
|
||||
{
|
||||
UInt32 curPtr = mTimeBoundsQueuePtr;
|
||||
UInt32 index = curPtr & kGeneralRingTimeBoundsQueueMask;
|
||||
CARingBuffer::TimeBounds* bounds = mTimeBoundsQueue + index;
|
||||
|
||||
startTime = bounds->mStartTime;
|
||||
endTime = bounds->mEndTime;
|
||||
UInt32 newPtr = bounds->mUpdateCounter;
|
||||
|
||||
if (newPtr == curPtr)
|
||||
return kCARingBufferError_OK;
|
||||
}
|
||||
return kCARingBufferError_CPUOverload;
|
||||
}
|
||||
|
||||
CARingBufferError CARingBuffer::ClipTimeBounds(SampleTime& startRead, SampleTime& endRead)
|
||||
{
|
||||
SampleTime startTime, endTime;
|
||||
|
||||
CARingBufferError err = GetTimeBounds(startTime, endTime);
|
||||
if (err) return err;
|
||||
|
||||
if (startRead > endTime || endRead < startTime) {
|
||||
endRead = startRead;
|
||||
return kCARingBufferError_OK;
|
||||
}
|
||||
|
||||
startRead = std::max(startRead, startTime);
|
||||
endRead = std::min(endRead, endTime);
|
||||
endRead = std::max(endRead, startRead);
|
||||
|
||||
return kCARingBufferError_OK; // success
|
||||
}
|
||||
|
||||
CARingBufferError CARingBuffer::Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime startRead)
|
||||
{
|
||||
if (nFrames == 0)
|
||||
return kCARingBufferError_OK;
|
||||
|
||||
startRead = std::max(0LL, startRead);
|
||||
|
||||
SampleTime endRead = startRead + nFrames;
|
||||
|
||||
SampleTime startRead0 = startRead;
|
||||
SampleTime endRead0 = endRead;
|
||||
|
||||
CARingBufferError err = ClipTimeBounds(startRead, endRead);
|
||||
if (err) return err;
|
||||
|
||||
if (startRead == endRead) {
|
||||
ZeroABL(abl, 0, nFrames * mBytesPerFrame);
|
||||
return kCARingBufferError_OK;
|
||||
}
|
||||
|
||||
SInt32 byteSize = (SInt32)((endRead - startRead) * mBytesPerFrame);
|
||||
|
||||
SInt32 destStartByteOffset = std::max((SInt32)0, (SInt32)((startRead - startRead0) * mBytesPerFrame));
|
||||
|
||||
if (destStartByteOffset > 0) {
|
||||
ZeroABL(abl, 0, std::min((SInt32)(nFrames * mBytesPerFrame), destStartByteOffset));
|
||||
}
|
||||
|
||||
SInt32 destEndSize = std::max((SInt32)0, (SInt32)(endRead0 - endRead));
|
||||
if (destEndSize > 0) {
|
||||
ZeroABL(abl, destStartByteOffset + byteSize, destEndSize * mBytesPerFrame);
|
||||
}
|
||||
|
||||
Byte **buffers = mBuffers;
|
||||
int offset0 = FrameOffset(startRead);
|
||||
int offset1 = FrameOffset(endRead);
|
||||
int nbytes;
|
||||
|
||||
if (offset0 < offset1) {
|
||||
nbytes = offset1 - offset0;
|
||||
FetchABL(abl, destStartByteOffset, buffers, offset0, nbytes);
|
||||
} else {
|
||||
nbytes = mCapacityBytes - offset0;
|
||||
FetchABL(abl, destStartByteOffset, buffers, offset0, nbytes);
|
||||
FetchABL(abl, destStartByteOffset + nbytes, buffers, 0, offset1);
|
||||
nbytes += offset1;
|
||||
}
|
||||
|
||||
int nchannels = abl->mNumberBuffers;
|
||||
AudioBuffer *dest = abl->mBuffers;
|
||||
while (--nchannels >= 0)
|
||||
{
|
||||
dest->mDataByteSize = nbytes;
|
||||
dest++;
|
||||
}
|
||||
|
||||
return noErr;
|
||||
}
|
||||
126
driver/PublicUtility/CARingBuffer.h
Normal file
126
driver/PublicUtility/CARingBuffer.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
File: CARingBuffer.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2014 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CARingBuffer_Header
|
||||
#define CARingBuffer_Header
|
||||
|
||||
enum {
|
||||
kCARingBufferError_OK = 0,
|
||||
kCARingBufferError_TooMuch = 3, // fetch start time is earlier than buffer start time and fetch end time is later than buffer end time
|
||||
kCARingBufferError_CPUOverload = 4 // the reader is unable to get enough CPU cycles to capture a consistent snapshot of the time bounds
|
||||
};
|
||||
|
||||
typedef SInt32 CARingBufferError;
|
||||
|
||||
const UInt32 kGeneralRingTimeBoundsQueueSize = 32;
|
||||
const UInt32 kGeneralRingTimeBoundsQueueMask = kGeneralRingTimeBoundsQueueSize - 1;
|
||||
|
||||
class CARingBuffer {
|
||||
public:
|
||||
typedef SInt64 SampleTime;
|
||||
|
||||
CARingBuffer();
|
||||
~CARingBuffer();
|
||||
|
||||
void Allocate(int nChannels, UInt32 bytesPerFrame, UInt32 capacityFrames);
|
||||
// capacityFrames will be rounded up to a power of 2
|
||||
void Deallocate();
|
||||
|
||||
CARingBufferError Store(const AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber);
|
||||
// Copy nFrames of data into the ring buffer at the specified sample time.
|
||||
// The sample time should normally increase sequentially, though gaps
|
||||
// are filled with zeroes. A sufficiently large gap effectively empties
|
||||
// the buffer before storing the new data.
|
||||
|
||||
// If frameNumber is less than the previous frame number, the behavior is undefined.
|
||||
|
||||
// Return false for failure (buffer not large enough).
|
||||
|
||||
CARingBufferError Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber);
|
||||
// will alter mDataByteSize of the buffers
|
||||
|
||||
CARingBufferError GetTimeBounds(SampleTime &startTime, SampleTime &endTime);
|
||||
|
||||
protected:
|
||||
|
||||
UInt32 FrameOffset(SampleTime frameNumber) { return (frameNumber & mCapacityFramesMask) * mBytesPerFrame; }
|
||||
|
||||
CARingBufferError ClipTimeBounds(SampleTime& startRead, SampleTime& endRead);
|
||||
|
||||
// these should only be called from Store.
|
||||
SampleTime StartTime() const { return mTimeBoundsQueue[mTimeBoundsQueuePtr & kGeneralRingTimeBoundsQueueMask].mStartTime; }
|
||||
SampleTime EndTime() const { return mTimeBoundsQueue[mTimeBoundsQueuePtr & kGeneralRingTimeBoundsQueueMask].mEndTime; }
|
||||
void SetTimeBounds(SampleTime startTime, SampleTime endTime);
|
||||
|
||||
protected:
|
||||
Byte ** mBuffers; // allocated in one chunk of memory
|
||||
int mNumberChannels;
|
||||
UInt32 mBytesPerFrame; // within one deinterleaved channel
|
||||
UInt32 mCapacityFrames; // per channel, must be a power of 2
|
||||
UInt32 mCapacityFramesMask;
|
||||
UInt32 mCapacityBytes; // per channel
|
||||
|
||||
// range of valid sample time in the buffer
|
||||
typedef struct {
|
||||
volatile SampleTime mStartTime;
|
||||
volatile SampleTime mEndTime;
|
||||
volatile UInt32 mUpdateCounter;
|
||||
} TimeBounds;
|
||||
|
||||
CARingBuffer::TimeBounds mTimeBoundsQueue[kGeneralRingTimeBoundsQueueSize];
|
||||
UInt32 mTimeBoundsQueuePtr;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
482
driver/PublicUtility/CAVolumeCurve.cpp
Normal file
482
driver/PublicUtility/CAVolumeCurve.cpp
Normal file
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
File: CAVolumeCurve.cpp
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#include "CAVolumeCurve.h"
|
||||
#include "CADebugMacros.h"
|
||||
#include <math.h>
|
||||
|
||||
//=============================================================================
|
||||
// CAVolumeCurve
|
||||
//=============================================================================
|
||||
|
||||
CAVolumeCurve::CAVolumeCurve()
|
||||
:
|
||||
mTag(0),
|
||||
mCurveMap(),
|
||||
mIsApplyingTransferFunction(true),
|
||||
mTransferFunction(kPow2Over1Curve),
|
||||
mRawToScalarExponentNumerator(2.0f),
|
||||
mRawToScalarExponentDenominator(1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
CAVolumeCurve::~CAVolumeCurve()
|
||||
{
|
||||
}
|
||||
|
||||
SInt32 CAVolumeCurve::GetMinimumRaw() const
|
||||
{
|
||||
SInt32 theAnswer = 0;
|
||||
|
||||
if(!mCurveMap.empty())
|
||||
{
|
||||
CurveMap::const_iterator theIterator = mCurveMap.begin();
|
||||
theAnswer = theIterator->first.mMinimum;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
SInt32 CAVolumeCurve::GetMaximumRaw() const
|
||||
{
|
||||
SInt32 theAnswer = 0;
|
||||
|
||||
if(!mCurveMap.empty())
|
||||
{
|
||||
CurveMap::const_iterator theIterator = mCurveMap.begin();
|
||||
std::advance(theIterator, static_cast<int>(mCurveMap.size() - 1));
|
||||
theAnswer = theIterator->first.mMaximum;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
Float32 CAVolumeCurve::GetMinimumDB() const
|
||||
{
|
||||
Float32 theAnswer = 0;
|
||||
|
||||
if(!mCurveMap.empty())
|
||||
{
|
||||
CurveMap::const_iterator theIterator = mCurveMap.begin();
|
||||
theAnswer = theIterator->second.mMinimum;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
Float32 CAVolumeCurve::GetMaximumDB() const
|
||||
{
|
||||
Float32 theAnswer = 0;
|
||||
|
||||
if(!mCurveMap.empty())
|
||||
{
|
||||
CurveMap::const_iterator theIterator = mCurveMap.begin();
|
||||
std::advance(theIterator, static_cast<int>(mCurveMap.size() - 1));
|
||||
theAnswer = theIterator->second.mMaximum;
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
void CAVolumeCurve::SetTransferFunction(UInt32 inTransferFunction)
|
||||
{
|
||||
mTransferFunction = inTransferFunction;
|
||||
|
||||
// figure out the co-efficients
|
||||
switch(inTransferFunction)
|
||||
{
|
||||
case kLinearCurve:
|
||||
mIsApplyingTransferFunction = false;
|
||||
mRawToScalarExponentNumerator = 1.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow1Over3Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 1.0f;
|
||||
mRawToScalarExponentDenominator = 3.0f;
|
||||
break;
|
||||
|
||||
case kPow1Over2Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 1.0f;
|
||||
mRawToScalarExponentDenominator = 2.0f;
|
||||
break;
|
||||
|
||||
case kPow3Over4Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 3.0f;
|
||||
mRawToScalarExponentDenominator = 4.0f;
|
||||
break;
|
||||
|
||||
case kPow3Over2Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 3.0f;
|
||||
mRawToScalarExponentDenominator = 2.0f;
|
||||
break;
|
||||
|
||||
case kPow2Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 2.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow3Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 3.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow4Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 4.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow5Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 5.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow6Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 6.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow7Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 7.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow8Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 8.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow9Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 9.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow10Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 10.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow11Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 11.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
case kPow12Over1Curve:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 12.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
mIsApplyingTransferFunction = true;
|
||||
mRawToScalarExponentNumerator = 2.0f;
|
||||
mRawToScalarExponentDenominator = 1.0f;
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
void CAVolumeCurve::AddRange(SInt32 inMinRaw, SInt32 inMaxRaw, Float32 inMinDB, Float32 inMaxDB)
|
||||
{
|
||||
CARawPoint theRaw(inMinRaw, inMaxRaw);
|
||||
CADBPoint theDB(inMinDB, inMaxDB);
|
||||
|
||||
bool isOverlapped = false;
|
||||
bool isDone = false;
|
||||
CurveMap::iterator theIterator = mCurveMap.begin();
|
||||
while((theIterator != mCurveMap.end()) && !isOverlapped && !isDone)
|
||||
{
|
||||
isOverlapped = CARawPoint::Overlap(theRaw, theIterator->first);
|
||||
isDone = theRaw >= theIterator->first;
|
||||
|
||||
if(!isOverlapped && !isDone)
|
||||
{
|
||||
std::advance(theIterator, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(!isOverlapped)
|
||||
{
|
||||
mCurveMap.insert(CurveMap::value_type(theRaw, theDB));
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugMessage("CAVolumeCurve::AddRange: new point overlaps");
|
||||
}
|
||||
}
|
||||
|
||||
void CAVolumeCurve::ResetRange()
|
||||
{
|
||||
mCurveMap.clear();
|
||||
}
|
||||
|
||||
bool CAVolumeCurve::CheckForContinuity() const
|
||||
{
|
||||
bool theAnswer = true;
|
||||
|
||||
CurveMap::const_iterator theIterator = mCurveMap.begin();
|
||||
if(theIterator != mCurveMap.end())
|
||||
{
|
||||
SInt32 theRaw = theIterator->first.mMinimum;
|
||||
Float32 theDB = theIterator->second.mMinimum;
|
||||
do
|
||||
{
|
||||
SInt32 theRawMin = theIterator->first.mMinimum;
|
||||
SInt32 theRawMax = theIterator->first.mMaximum;
|
||||
SInt32 theRawRange = theRawMax - theRawMin;
|
||||
|
||||
Float32 theDBMin = theIterator->second.mMinimum;
|
||||
Float32 theDBMax = theIterator->second.mMaximum;
|
||||
Float32 theDBRange = theDBMax - theDBMin;
|
||||
|
||||
theAnswer = theRaw == theRawMin;
|
||||
theAnswer = theAnswer && (theDB == theDBMin);
|
||||
|
||||
theRaw += theRawRange;
|
||||
theDB += theDBRange;
|
||||
|
||||
std::advance(theIterator, 1);
|
||||
}
|
||||
while((theIterator != mCurveMap.end()) && theAnswer);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
SInt32 CAVolumeCurve::ConvertDBToRaw(Float32 inDB) const
|
||||
{
|
||||
// clamp the value to the dB range
|
||||
Float32 theOverallDBMin = GetMinimumDB();
|
||||
Float32 theOverallDBMax = GetMaximumDB();
|
||||
|
||||
if(inDB < theOverallDBMin) inDB = theOverallDBMin;
|
||||
if(inDB > theOverallDBMax) inDB = theOverallDBMax;
|
||||
|
||||
// get the first entry in the curve map;
|
||||
CurveMap::const_iterator theIterator = mCurveMap.begin();
|
||||
|
||||
// initialize the answer to the minimum raw of the first item in the curve map
|
||||
SInt32 theAnswer = theIterator->first.mMinimum;
|
||||
|
||||
// iterate through the curve map until we run out of dB
|
||||
bool isDone = false;
|
||||
while(!isDone && (theIterator != mCurveMap.end()))
|
||||
{
|
||||
SInt32 theRawMin = theIterator->first.mMinimum;
|
||||
SInt32 theRawMax = theIterator->first.mMaximum;
|
||||
SInt32 theRawRange = theRawMax - theRawMin;
|
||||
|
||||
Float32 theDBMin = theIterator->second.mMinimum;
|
||||
Float32 theDBMax = theIterator->second.mMaximum;
|
||||
Float32 theDBRange = theDBMax - theDBMin;
|
||||
|
||||
Float32 theDBPerRaw = theDBRange / static_cast<Float32>(theRawRange);
|
||||
|
||||
// figure out how many steps we are into this entry in the curve map
|
||||
if(inDB > theDBMax)
|
||||
{
|
||||
// we're past the end of this one, so add in the whole range for this entry
|
||||
theAnswer += theRawRange;
|
||||
}
|
||||
else
|
||||
{
|
||||
// it's somewhere within the current entry
|
||||
// figure out how many steps it is
|
||||
Float32 theNumberRawSteps = inDB - theDBMin;
|
||||
theNumberRawSteps /= theDBPerRaw;
|
||||
|
||||
// only move in whole steps
|
||||
theNumberRawSteps = roundf(theNumberRawSteps);
|
||||
|
||||
// add this many steps to the answer
|
||||
theAnswer += static_cast<SInt32>(theNumberRawSteps);
|
||||
|
||||
// mark that we are done
|
||||
isDone = true;
|
||||
}
|
||||
|
||||
// go to the next entry in the curve map
|
||||
std::advance(theIterator, 1);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
Float32 CAVolumeCurve::ConvertRawToDB(SInt32 inRaw) const
|
||||
{
|
||||
Float32 theAnswer = 0;
|
||||
|
||||
// clamp the raw value
|
||||
SInt32 theOverallRawMin = GetMinimumRaw();
|
||||
SInt32 theOverallRawMax = GetMaximumRaw();
|
||||
|
||||
if(inRaw < theOverallRawMin) inRaw = theOverallRawMin;
|
||||
if(inRaw > theOverallRawMax) inRaw = theOverallRawMax;
|
||||
|
||||
// figure out how many raw steps need to be taken from the first one
|
||||
SInt32 theNumberRawSteps = inRaw - theOverallRawMin;
|
||||
|
||||
// get the first item in the curve map
|
||||
CurveMap::const_iterator theIterator = mCurveMap.begin();
|
||||
|
||||
// initialize the answer to the minimum dB of the first item in the curve map
|
||||
theAnswer = theIterator->second.mMinimum;
|
||||
|
||||
// iterate through the curve map until we run out of steps
|
||||
while((theNumberRawSteps > 0) && (theIterator != mCurveMap.end()))
|
||||
{
|
||||
// compute some values
|
||||
SInt32 theRawMin = theIterator->first.mMinimum;
|
||||
SInt32 theRawMax = theIterator->first.mMaximum;
|
||||
SInt32 theRawRange = theRawMax - theRawMin;
|
||||
|
||||
Float32 theDBMin = theIterator->second.mMinimum;
|
||||
Float32 theDBMax = theIterator->second.mMaximum;
|
||||
Float32 theDBRange = theDBMax - theDBMin;
|
||||
|
||||
Float32 theDBPerRaw = theDBRange / static_cast<Float32>(theRawRange);
|
||||
|
||||
// there might be more steps than the current map entry accounts for
|
||||
SInt32 theRawStepsToAdd = std::min(theRawRange, theNumberRawSteps);
|
||||
|
||||
// add this many steps worth of db to the answer;
|
||||
theAnswer += theRawStepsToAdd * theDBPerRaw;
|
||||
|
||||
// figure out how many steps are left
|
||||
theNumberRawSteps -= theRawStepsToAdd;
|
||||
|
||||
// go to the next map entry
|
||||
std::advance(theIterator, 1);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
Float32 CAVolumeCurve::ConvertRawToScalar(SInt32 inRaw) const
|
||||
{
|
||||
// get some important values
|
||||
Float32 theDBMin = GetMinimumDB();
|
||||
Float32 theDBMax = GetMaximumDB();
|
||||
Float32 theDBRange = theDBMax - theDBMin;
|
||||
SInt32 theRawMin = GetMinimumRaw();
|
||||
SInt32 theRawMax = GetMaximumRaw();
|
||||
SInt32 theRawRange = theRawMax - theRawMin;
|
||||
|
||||
// range the raw value
|
||||
if(inRaw < theRawMin) inRaw = theRawMin;
|
||||
if(inRaw > theRawMax) inRaw = theRawMax;
|
||||
|
||||
// calculate the distance in the range inRaw is
|
||||
Float32 theAnswer = static_cast<Float32>(inRaw - theRawMin) / static_cast<Float32>(theRawRange);
|
||||
|
||||
// only apply a curve to the scalar values if the dB range is greater than 30
|
||||
if(mIsApplyingTransferFunction && (theDBRange > 30.0f))
|
||||
{
|
||||
theAnswer = powf(theAnswer, mRawToScalarExponentNumerator / mRawToScalarExponentDenominator);
|
||||
}
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
Float32 CAVolumeCurve::ConvertDBToScalar(Float32 inDB) const
|
||||
{
|
||||
SInt32 theRawValue = ConvertDBToRaw(inDB);
|
||||
Float32 theAnswer = ConvertRawToScalar(theRawValue);
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
SInt32 CAVolumeCurve::ConvertScalarToRaw(Float32 inScalar) const
|
||||
{
|
||||
// range the scalar value
|
||||
inScalar = std::min(1.0f, std::max(0.0f, inScalar));
|
||||
|
||||
// get some important values
|
||||
Float32 theDBMin = GetMinimumDB();
|
||||
Float32 theDBMax = GetMaximumDB();
|
||||
Float32 theDBRange = theDBMax - theDBMin;
|
||||
SInt32 theRawMin = GetMinimumRaw();
|
||||
SInt32 theRawMax = GetMaximumRaw();
|
||||
SInt32 theRawRange = theRawMax - theRawMin;
|
||||
|
||||
// have to undo the curve if the dB range is greater than 30
|
||||
if(mIsApplyingTransferFunction && (theDBRange > 30.0f))
|
||||
{
|
||||
inScalar = powf(inScalar, mRawToScalarExponentDenominator / mRawToScalarExponentNumerator);
|
||||
}
|
||||
|
||||
// now we can figure out how many raw steps this is
|
||||
Float32 theNumberRawSteps = inScalar * static_cast<Float32>(theRawRange);
|
||||
theNumberRawSteps = roundf(theNumberRawSteps);
|
||||
|
||||
// the answer is the minimum raw value plus the number of raw steps
|
||||
SInt32 theAnswer = theRawMin + static_cast<SInt32>(theNumberRawSteps);
|
||||
|
||||
return theAnswer;
|
||||
}
|
||||
|
||||
Float32 CAVolumeCurve::ConvertScalarToDB(Float32 inScalar) const
|
||||
{
|
||||
SInt32 theRawValue = ConvertScalarToRaw(inScalar);
|
||||
Float32 theAnswer = ConvertRawToDB(theRawValue);
|
||||
return theAnswer;
|
||||
}
|
||||
178
driver/PublicUtility/CAVolumeCurve.h
Normal file
178
driver/PublicUtility/CAVolumeCurve.h
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
File: CAVolumeCurve.h
|
||||
Abstract: Part of CoreAudio Utility Classes
|
||||
Version: 1.0.1
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
#if !defined(__CAVolumeCurve_h__)
|
||||
#define __CAVolumeCurve_h__
|
||||
|
||||
//=============================================================================
|
||||
// Includes
|
||||
//=============================================================================
|
||||
|
||||
#if !defined(__COREAUDIO_USE_FLAT_INCLUDES__)
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#else
|
||||
#include <CoreAudioTypes.h>
|
||||
#endif
|
||||
#include <map>
|
||||
|
||||
//=============================================================================
|
||||
// Types
|
||||
//=============================================================================
|
||||
|
||||
struct CARawPoint
|
||||
{
|
||||
SInt32 mMinimum;
|
||||
SInt32 mMaximum;
|
||||
|
||||
CARawPoint() : mMinimum(0), mMaximum(0) {}
|
||||
CARawPoint(const CARawPoint& inPoint) : mMinimum(inPoint.mMinimum), mMaximum(inPoint.mMaximum) {}
|
||||
CARawPoint(SInt32 inMinimum, SInt32 inMaximum) : mMinimum(inMinimum), mMaximum(inMaximum) {}
|
||||
CARawPoint& operator=(const CARawPoint& inPoint) { mMinimum = inPoint.mMinimum; mMaximum = inPoint.mMaximum; return *this; }
|
||||
|
||||
static bool Overlap(const CARawPoint& x, const CARawPoint& y) { return (x.mMinimum < y.mMaximum) && (x.mMaximum > y.mMinimum); }
|
||||
};
|
||||
|
||||
inline bool operator<(const CARawPoint& x, const CARawPoint& y) { return x.mMinimum < y.mMinimum; }
|
||||
inline bool operator==(const CARawPoint& x, const CARawPoint& y) { return (x.mMinimum == y.mMinimum) && (x.mMaximum == y.mMaximum); }
|
||||
inline bool operator!=(const CARawPoint& x, const CARawPoint& y) { return !(x == y); }
|
||||
inline bool operator<=(const CARawPoint& x, const CARawPoint& y) { return (x < y) || (x == y); }
|
||||
inline bool operator>=(const CARawPoint& x, const CARawPoint& y) { return !(x < y); }
|
||||
inline bool operator>(const CARawPoint& x, const CARawPoint& y) { return !((x < y) || (x == y)); }
|
||||
|
||||
struct CADBPoint
|
||||
{
|
||||
Float32 mMinimum;
|
||||
Float32 mMaximum;
|
||||
|
||||
CADBPoint() : mMinimum(0), mMaximum(0) {}
|
||||
CADBPoint(const CADBPoint& inPoint) : mMinimum(inPoint.mMinimum), mMaximum(inPoint.mMaximum) {}
|
||||
CADBPoint(Float32 inMinimum, Float32 inMaximum) : mMinimum(inMinimum), mMaximum(inMaximum) {}
|
||||
CADBPoint& operator=(const CADBPoint& inPoint) { mMinimum = inPoint.mMinimum; mMaximum = inPoint.mMaximum; return *this; }
|
||||
|
||||
static bool Overlap(const CADBPoint& x, const CADBPoint& y) { return (x.mMinimum < y.mMaximum) && (x.mMaximum >= y.mMinimum); }
|
||||
};
|
||||
|
||||
inline bool operator<(const CADBPoint& x, const CADBPoint& y) { return x.mMinimum < y.mMinimum; }
|
||||
inline bool operator==(const CADBPoint& x, const CADBPoint& y) { return (x.mMinimum == y.mMinimum) && (x.mMaximum == y.mMaximum); }
|
||||
inline bool operator!=(const CADBPoint& x, const CADBPoint& y) { return !(x == y); }
|
||||
inline bool operator<=(const CADBPoint& x, const CADBPoint& y) { return (x < y) || (x == y); }
|
||||
inline bool operator>=(const CADBPoint& x, const CADBPoint& y) { return !(x < y); }
|
||||
inline bool operator>(const CADBPoint& x, const CADBPoint& y) { return !((x < y) || (x == y)); }
|
||||
|
||||
//=============================================================================
|
||||
// CAVolumeCurve
|
||||
//=============================================================================
|
||||
|
||||
class CAVolumeCurve
|
||||
{
|
||||
|
||||
// Constants
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kLinearCurve = 0,
|
||||
kPow1Over3Curve = 1,
|
||||
kPow1Over2Curve = 2,
|
||||
kPow3Over4Curve = 3,
|
||||
kPow3Over2Curve = 4,
|
||||
kPow2Over1Curve = 5,
|
||||
kPow3Over1Curve = 6,
|
||||
kPow4Over1Curve = 7,
|
||||
kPow5Over1Curve = 8,
|
||||
kPow6Over1Curve = 9,
|
||||
kPow7Over1Curve = 10,
|
||||
kPow8Over1Curve = 11,
|
||||
kPow9Over1Curve = 12,
|
||||
kPow10Over1Curve = 13,
|
||||
kPow11Over1Curve = 14,
|
||||
kPow12Over1Curve = 15
|
||||
};
|
||||
|
||||
// Construction/Destruction
|
||||
public:
|
||||
CAVolumeCurve();
|
||||
virtual ~CAVolumeCurve();
|
||||
|
||||
// Attributes
|
||||
public:
|
||||
UInt32 GetTag() const { return mTag; }
|
||||
void SetTag(UInt32 inTag) { mTag = inTag; }
|
||||
SInt32 GetMinimumRaw() const;
|
||||
SInt32 GetMaximumRaw() const;
|
||||
Float32 GetMinimumDB() const;
|
||||
Float32 GetMaximumDB() const;
|
||||
|
||||
void SetIsApplyingTransferFunction(bool inIsApplyingTransferFunction) { mIsApplyingTransferFunction = inIsApplyingTransferFunction; }
|
||||
UInt32 GetTransferFunction() const { return mTransferFunction; }
|
||||
void SetTransferFunction(UInt32 inTransferFunction);
|
||||
|
||||
// Operations
|
||||
public:
|
||||
void AddRange(SInt32 mMinRaw, SInt32 mMaxRaw, Float32 inMinDB, Float32 inMaxDB);
|
||||
void ResetRange();
|
||||
bool CheckForContinuity() const;
|
||||
|
||||
SInt32 ConvertDBToRaw(Float32 inDB) const;
|
||||
Float32 ConvertRawToDB(SInt32 inRaw) const;
|
||||
Float32 ConvertRawToScalar(SInt32 inRaw) const;
|
||||
Float32 ConvertDBToScalar(Float32 inDB) const;
|
||||
SInt32 ConvertScalarToRaw(Float32 inScalar) const;
|
||||
Float32 ConvertScalarToDB(Float32 inScalar) const;
|
||||
|
||||
// Implementation
|
||||
private:
|
||||
typedef std::map<CARawPoint, CADBPoint> CurveMap;
|
||||
|
||||
UInt32 mTag;
|
||||
CurveMap mCurveMap;
|
||||
bool mIsApplyingTransferFunction;
|
||||
UInt32 mTransferFunction;
|
||||
Float32 mRawToScalarExponentNumerator;
|
||||
Float32 mRawToScalarExponentDenominator;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user