目次

include/AK/Tools/Mac/AkPlatformFuncs.h

説明を見る。
00001 
00002 //
00003 // AkPlatformFuncs.h 
00004 //
00005 // Audiokinetic platform-dependent functions definition.
00006 //
00007 // Copyright (c) 2006 Audiokinetic Inc. / All Rights Reserved
00008 //
00010 
00011 #pragma once
00012 
00013 #include <AK/Tools/Common/AkAssert.h>
00014 #include <AK/SoundEngine/Common/AkTypes.h>
00015 
00016 #include <mach/task.h>
00017 #include <mach/semaphore.h>
00018 #include <CoreFoundation/CFString.h>
00019 #include <libkern/OSAtomic.h>
00020 #include <mach/task.h>
00021 #include <mach/mach_init.h>
00022 #include <mach/mach_time.h>
00023 #include <wchar.h>
00024 
00025 namespace AKPLATFORM
00026 {
00027     extern inline size_t AkUtf16StrLen( const AkUtf16* in_pStr );
00028     // Simple automatic event API
00029     // ------------------------------------------------------------------
00030     
00032     inline void AkClearEvent( AkEvent & out_event )
00033     {
00034         out_event = 0;
00035     }
00036     
00038     inline AKRESULT AkCreateEvent( AkEvent & out_event )
00039     {
00040         kern_return_t ret = semaphore_create(   
00041                             mach_task_self(),
00042                             &out_event,
00043                             SYNC_POLICY_FIFO,
00044                             0 );
00045         
00046         return ( ret == noErr  ) ? AK_Success : AK_Fail;
00047     }
00048 
00049     inline AKRESULT AkCreateSemaphore( AkSemaphore & out_semaphore, AkUInt32 in_initialCount )
00050     {
00051         kern_return_t ret = semaphore_create(   
00052                             mach_task_self(),
00053                             &out_semaphore,
00054                             SYNC_POLICY_FIFO,
00055                             in_initialCount );
00056         
00057         return ( ret == noErr  ) ? AK_Success : AK_Fail;    
00058     }
00059     
00061     inline void AkDestroyEvent( AkEvent & io_event )
00062     {
00063         if( io_event != 0 )
00064         {
00065             AKVERIFY( semaphore_destroy( mach_task_self(), io_event ) == noErr);
00066         }
00067         io_event = 0;
00068     }
00069 
00071     inline void AkDestroySemaphore( AkSemaphore & io_semaphore )
00072     {
00073         if( io_semaphore != 0 )
00074         {
00075             AKVERIFY( semaphore_destroy( mach_task_self(), io_semaphore ) == noErr);
00076         }
00077         io_semaphore = 0;
00078     }   
00079     
00081     inline void AkWaitForEvent( AkEvent & in_event )
00082     {
00083         AKVERIFY( semaphore_wait( in_event ) == noErr );
00084     }
00085     
00086     inline void AkWaitForSemaphore( AkSemaphore & in_semaphore )
00087     {
00088         AKVERIFY( semaphore_wait( in_semaphore ) == noErr );
00089     }
00090 
00092     inline void AkSignalEvent( const AkEvent & in_event )
00093     {
00094         AKVERIFY( semaphore_signal( in_event ) == noErr );
00095     }
00096     
00097     inline void AkReleaseSemaphore( const AkSemaphore & in_event )
00098     {
00099         AKVERIFY( semaphore_signal( in_event ) == noErr );
00100     }
00101     
00102     // Atomic Operations
00103     // ------------------------------------------------------------------
00104 
00106     inline AkInt32 AkInterlockedIncrement( AkInt32 * pValue )
00107     {
00108         return OSAtomicIncrement32( pValue );
00109     }
00110 
00112     inline AkInt32 AkInterlockedDecrement( AkInt32 * pValue )
00113     {
00114         return OSAtomicDecrement32( pValue );
00115     }
00116 
00117     inline bool AkInterlockedCompareExchange( volatile AkInt32* io_pDest, AkInt32 in_newValue, AkInt32 in_expectedOldVal )
00118     {
00119         return OSAtomicCompareAndSwapInt(in_expectedOldVal, in_newValue, io_pDest);
00120     }
00121 
00122     inline bool AkInterlockedCompareExchange( volatile AkInt64* io_pDest, AkInt64 in_newValue, AkInt64 in_expectedOldVal )
00123     {
00124         return OSAtomicCompareAndSwap64(in_expectedOldVal, in_newValue, io_pDest);
00125     }
00126 
00127     inline bool AkInterlockedCompareExchange( volatile AkIntPtr* io_pDest, AkIntPtr in_newValue, AkIntPtr in_expectedOldVal )
00128     {
00129 #ifndef AK_IOS
00130         if (sizeof(io_pDest) == 8)
00131             return OSAtomicCompareAndSwap64(( AkInt64)in_expectedOldVal, (AkInt64)in_newValue, (volatile AkInt64*)io_pDest);
00132 #endif // #ifndef AK_IOS
00133         return OSAtomicCompareAndSwapInt((AkInt32)in_expectedOldVal, (AkInt32)in_newValue, (AkInt32*)io_pDest);
00134     }
00135 
00136     inline void AkMemoryBarrier()
00137     {
00138         OSMemoryBarrier();
00139     }
00140     
00141     // Time functions
00142     // ------------------------------------------------------------------
00143 
00145     inline void PerformanceCounter( AkInt64 * out_piLastTime )
00146     {
00147         *out_piLastTime = mach_absolute_time();
00148     }
00149 
00151     inline void PerformanceFrequency( AkInt64 * out_piFreq )
00152     {
00153         static mach_timebase_info_data_t    sTimebaseInfo;
00154         mach_timebase_info(&sTimebaseInfo);
00155         if ( sTimebaseInfo.numer !=0 )
00156         {
00157             *out_piFreq = AkInt64((1E9 * sTimebaseInfo.denom) / sTimebaseInfo.numer );
00158         }
00159         else
00160         {
00161             *out_piFreq = 0;
00162         }
00163     }
00164 
00165 
00166     template<class destType, class srcType>
00167     inline size_t AkMacConvertString( destType* in_pdDest, const srcType* in_pSrc, size_t in_MaxSize, size_t destStrLen(const destType *),  size_t srcStrLen(const srcType *) )
00168     { 
00169         CFStringBuiltInEncodings dstEncoding;       
00170         CFStringBuiltInEncodings srcEncoding;
00171         switch(sizeof(destType))
00172         {
00173             case 1:
00174                 dstEncoding = kCFStringEncodingUTF8;
00175                 break;
00176             case 2:
00177                 dstEncoding = kCFStringEncodingUTF16LE;
00178                 break;
00179             case 4:
00180                 dstEncoding = kCFStringEncodingUTF32LE;
00181                 break;
00182             default:
00183                 AKASSERT(!"Invalid Char size");
00184         }
00185         
00186         switch(sizeof(srcType))
00187         {
00188             case 1:
00189                 srcEncoding = kCFStringEncodingUTF8;
00190                 break;
00191             case 2:
00192                 srcEncoding = kCFStringEncodingUTF16LE;
00193                 break;
00194             case 4:
00195                 srcEncoding = kCFStringEncodingUTF32LE;
00196                 break;
00197             default:
00198                 AKASSERT(!"Invalid Char size");
00199         }
00200         
00201         CFStringRef strRef;
00202         strRef = CFStringCreateWithBytes(   nil, 
00203                                          (UInt8 *) in_pSrc,
00204                                          (srcStrLen( in_pSrc ) + 1) * sizeof(srcType),
00205                                          srcEncoding,
00206                                          false );
00207         CFRange rangeToProcess = CFRangeMake(0, CFStringGetLength(strRef));
00208         CFIndex sizeConverted = CFStringGetBytes(strRef, rangeToProcess, dstEncoding, '?', false, (UInt8 *)in_pdDest , in_MaxSize * sizeof(destType), NULL);
00209         
00210         //WG-28497 Memory leak when converting strings on Mac & iOS
00211         CFRelease(strRef);
00212         
00213         return sizeConverted;
00214     }
00215 
00216     #define CONVERT_UTF16_TO_WCHAR( _astring_, _wcharstring_ ) \
00217         _wcharstring_ = (wchar_t*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(wchar_t) ); \
00218         AK_UTF16_TO_WCHAR(  _wcharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 )
00219     
00220     #define CONVERT_WCHAR_TO_UTF16( _astring_, _utf16string_ ) \
00221         _utf16string_ = (AkUtf16*)AkAlloca( (1 + wcslen(_astring_)) * sizeof(AkUtf16) ); \
00222         AK_WCHAR_TO_UTF16(  _utf16string_, (const wchar_t*)_astring_, wcslen(_astring_)+1 )
00223 
00224     #define CONVERT_OSCHAR_TO_UTF16( _astring_, _utf16string_ ) \
00225         _utf16string_ = (AkUtf16*)AkAlloca( (1 + strlen(_astring_)) * sizeof(AkUtf16) ); \
00226         AK_OSCHAR_TO_UTF16( _utf16string_, (const AkOSChar*)_astring_, strlen(_astring_)+1 )
00227 
00228     #define CONVERT_UTF16_TO_OSCHAR( _astring_, _oscharstring_ ) \
00229         _oscharstring_ = (AkOSChar*)AkAlloca( (1 + AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)) * sizeof(AkOSChar) ); \
00230         AK_UTF16_TO_OSCHAR( _oscharstring_, (const AkUtf16*)_astring_, AKPLATFORM::AkUtf16StrLen((const AkUtf16*)_astring_)+1 ) 
00231 
00232     #define AK_UTF16_TO_WCHAR(  in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<wchar_t, AkUtf16>(   in_pdDest, in_pSrc, in_MaxSize, &wcslen , &AKPLATFORM::AkUtf16StrLen)
00233     #define AK_WCHAR_TO_UTF16(  in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkUtf16, wchar_t>(   in_pdDest, in_pSrc, in_MaxSize, &AKPLATFORM::AkUtf16StrLen, &wcslen )
00234     #define AK_UTF16_TO_OSCHAR( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkOSChar, AkUtf16>(  in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00235     #define AK_UTF16_TO_CHAR(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<char, AkUtf16>(  in_pdDest, in_pSrc, in_MaxSize, strlen, AKPLATFORM::AkUtf16StrLen )
00236     #define AK_CHAR_TO_UTF16(   in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkUtf16, char>(  in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)  
00237     #define AK_OSCHAR_TO_UTF16( in_pdDest, in_pSrc, in_MaxSize )    AKPLATFORM::AkMacConvertString<AkUtf16, AkOSChar>(  in_pdDest, in_pSrc, in_MaxSize, AKPLATFORM::AkUtf16StrLen, strlen)  
00238     
00240     #define AkAlloca( _size_ ) alloca( _size_ )
00241 }